[Tarjan][基环树]JZOJ 4221 互相追逐的点
分析
这可真是浪漫的爱情故事啊
原题目名称叫做WYF互相追逐的头(有点搞笑??)
水题,基环树
把环抠出来输出
话说我都没考虑自环都A了呢
#include <iostream> #include <cstdio> using namespace std; const int N=2e5+10; struct Edge { int u,v,nx; }g[N]; int cnt,list[N],id[N]; int stack[N],low[N],dfn[N],stk[N],sz[N]; bool instk[N]; int tme,top,tp,idcnt; int n; void Add(int u,int v) {g[++cnt]=(Edge){u,v,list[u]};list[u]=cnt;} void Tarjan(int v0) { stack[++tp]=v0; while (tp) { int u=stack[tp],i; if (!dfn[u]) low[u]=dfn[u]=++tme,stk[++top]=u,instk[u]=1; for (i=list[u];i;i=g[i].nx) if (!dfn[g[i].v]) break; else if (instk[g[i].v]) low[u]=min(low[u],dfn[g[i].v]); if (!i&&tp>1) low[stack[tp-1]]=min(low[stack[tp-1]],low[u]); if (!i) { if (dfn[u]==low[u]) { ++idcnt; do { id[stk[top]]=idcnt;instk[stk[top]]=0;sz[idcnt]++; } while (stk[top--]!=u); } tp--; } else stack[++tp]=g[i].v; } } int main() { scanf("%d",&n); for (int i=1,v;i<=n;i++) scanf("%d",&v),Add(i,v); for (int i=1;i<=n;i++) if (!dfn[i]) Tarjan(i); for (int i=1;i<=idcnt;i++) if (sz[i]>1) { printf("%d\n",sz[i]); for (int j=1;j<=n;j++) if (id[j]==i) printf("%d ",j); } }
在日渐沉没的世界里,我发现了你。