23333怎么调了一晚上。。。。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 100500 #define maxe 100500 using namespace std; struct edge { int v,nxt; }e[maxe]; int n,xx[maxv],g[maxv],nume=0,dfn[maxv],low[maxv],times=0,stack[maxv],top=0,dp[maxv],ret=0,hash[maxv]; bool vis[maxv]; void addedge(int u,int v) { e[++nume].v=v; e[nume].nxt=g[u]; g[u]=nume; } void tarjan(int x) { vis[x]=true;dfn[x]=low[x]=++times;stack[++top]=x; for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (!vis[v]) { tarjan(v); low[x]=min(low[x],low[v]); } else low[x]=min(low[x],dfn[v]); } if (dfn[x]==low[x]) { int p=top,cnt=0;ret++; while (dfn[stack[p]]!=low[stack[p]]) { cnt++; p--; } cnt++; while (dfn[stack[top]]!=low[stack[top]]) { hash[stack[top]]=ret; if (cnt!=1) dp[stack[top]]=cnt; top--; } hash[stack[top]]=ret; if (cnt!=1) dp[stack[top]]=cnt; top--; } } int find(int x) { if (dp[x]) return dp[x]; else if (xx[x]==x) {dp[x]=1;return 1;} else return dp[x]=find(xx[x])+1; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d",&xx[i]); if (i!=xx[i]) addedge(i,xx[i]); } for (int i=1;i<=n;i++) { if (!vis[i]) tarjan(i); } for (int i=1;i<=n;i++) { if (i==xx[i]) { dp[i]=1; printf("1\n"); } else printf("%d\n",find(i)); } return 0; }
原文:http://www.cnblogs.com/ziliuziliu/p/5831265.html