kosaraju求调

P2921 [USACO08DEC] Trick or Treat on the Farm G

```cpp #include<cstdio> #include<algorithm> #include<vector> #include<cstring> #define N 114514 using namespace std; int head[N],dp[N],ans[N],nextt[N],cmp[N],sz[N],to[N],nxt[N],rh[N],rt[N],rn[N],rr[N],tot,n,f[N],cnt,vis[N]; void find(int p,int x,int dep){ if(ans){ ans[p]=ans[x]+dep; return; } return find(p,nextt[x],dep+1); } vector<int >out; void add(int u,int v){ to[++tot]=v,rt[tot]=u; nxt[tot]=head[u],rn[tot]=rh[v]; head[u]=tot,rh[v]=tot; } void dfs(int x){ vis[x]=1; for(int i=head[x];i;i=nxt[i]){ int y=to[i]; if(!vis[y])dfs(y); } out.push_back(x); } void rd(int x,int ff){ vis[x]=1;cmp[x]=ff; for(int i=rh[x];i;i=rn[i]){ int y=rt[i]; if(!vis[y])rd(y,ff); } } int kosaraju(){ memset(vis,0,sizeof(vis)); out.clear(); for(int i=1;i<=n;i++)if(!vis[i])dfs(i); int f=0; memset(vis,0,sizeof(vis)); for(int i=out.size()-1;i>=0;i--)if(!vis[out[i]])rd(out[i],++f); return f; } signed main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ int k=0;scanf("%d",&nextt[i]); add(i,nextt[i]); if(nextt[i]==i)ans[i]=1; } int sb=kosaraju(); for(int i=1;i<=n;i++)sz[cmp[i]]++; for(int i=1;i<=n;i++)if(sz[cmp[i]]!=1)ans[i]=sz[cmp[i]]; for(int i=1;i<=n;i++){ if(ans[i]==0)find(i,nextt[i],1); } for(int i=1;i<=n;i++){ printf("%d\n",ans[i]); } return 0; } ```
by 黑影洞人 @ 2022-03-06 08:35:45


|