bzoj1589 [Usaco2008 Dec]Trick or Treat on the Farm 采集糖果
本来想做强连通分量的题的
然而这个题太水了。。。随便搞搞就过了
一个连通块里有且仅有一个环,从所有入度为0的点出发找出环,记录答案
然后只有一个圈但没有“把”的再来考虑
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define inout(x) printf("%d",(x)) 17 #define douin(x) scanf("%lf",&x) 18 #define strin(x) scanf("%s",(x)) 19 #define LLin(x) scanf("%lld",&x) 20 #define op operator 21 #define CSC main 22 typedef unsigned long long ULL; 23 typedef const int cint; 24 typedef long long LL; 25 using namespace std; 26 void inin(int &ret) 27 { 28 ret=0;int f=0;char ch=getchar(); 29 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} 30 while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar(); 31 ret=f?-ret:ret; 32 } 33 int n,next[100010],du[100010],dfn[100010],dis[100010],sta[100010],top; 34 int main() 35 { 36 inin(n); 37 re(i,1,n)inin(next[i]),du[next[i]]++; 38 re(i,1,n)if(!du[i]) 39 { 40 int x=i; 41 dfn[x]=1;sta[++top]=x; 42 while(1) 43 { 44 if(dis[next[x]]) 45 { 46 int temp=0; 47 while(top)dis[sta[top--]]=++temp+dis[next[x]]; 48 break; 49 } 50 if(dfn[next[x]])break; 51 dfn[next[x]]=dfn[x]+1,x=next[x],sta[++top]=x; 52 } 53 if(top) 54 { 55 int huan=dfn[x]-dfn[next[x]]+1,qi=next[x]; 56 while(top) 57 { 58 int y=sta[top--]; 59 if(dfn[y]<dfn[qi])dis[y]=dis[qi]+dfn[qi]-dfn[y]; 60 else dis[y]=huan; 61 } 62 } 63 } 64 re(i,1,n)if(!dis[i]) 65 { 66 int x=i; 67 dfn[x]=1;sta[++top]=x; 68 while(!dfn[next[x]])dfn[next[x]]=dfn[x]+1,x=next[x],sta[++top]=x; 69 int huan=dfn[x]-dfn[next[x]]+1; 70 while(top)dis[sta[top--]]=huan; 71 } 72 re(i,1,n)printf("%d\n",dis[i]); 73 return 0; 74 }