每一年萬聖節,威斯康星的奶牛們都要打扮一番,出門在農場的N個牛棚裏轉 悠,來採集糖果.她們每走到一個不曾通過的牛棚,就會採集這個棚裏的1顆糖果.ios
農場不大,因此約翰要想盡法子讓奶牛們獲得快樂.他給每個牛棚設置了一個「後繼牛 棚」.牛棚i的後繼牛棚是next_i 他告訴奶牛們,她們到了一個牛棚以後,只要再日後繼牛棚走去, 就能夠蒐集到不少糖果.事實上這是一種有點欺騙意味的手段,來節約他的糖果.數組
第i只奶牛從牛棚i開始她的旅程.請你計算,每一隻奶牛能夠採集到多少糖果.spa
輸入格式:code
Line 1: A single integer: Nblog
輸出格式:ci
4 1 3 2 3
1 2 2 3
Four stalls.it
Stall 1 directs the cow back to stall 1.io
Stall 2 directs the cow to stall 3ast
Stall 3 directs the cow to stall 2class
Cow 1: Start at 1, next is 1. Total stalls visited: 1.
Cow 2: Start at 2, next is 3, next is 2. Total stalls visited: 2. Cow 3: Start at 3, next is 2, next is 3. Total stalls visited: 2. Cow 4: Start at 4, next is 3, next is 2, next is 3. Total stalls visited: 3.
1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #define time dscada 5 using namespace std; 6 7 int n,l,cnt,top,next[100050],summ[100050],pre[100050],time,last[100050],other[100050],f[100050],dfn[100050],low[100050],stack[100050],huan[100050]; 8 bool cir[100050],vis[100050]; 9 10 void add(int u,int v) { 11 pre[++l]=last[u]; 12 last[u]=l; 13 other[l]=v; 14 } 15 16 void tarjan(int x) { 17 dfn[x]=low[x]=++time; 18 stack[++top]=x; 19 vis[x]=1; 20 for (int p=last[x]; p; p=pre[p]) { 21 int q=other[p]; 22 if (!dfn[q]) { 23 tarjan(q); 24 low[x]=min(low[x],low[q]); 25 } else if (vis[q]) low[x]=min(low[x],dfn[q]); 26 } 27 if (dfn[x]==low[x]) { 28 int sum=0; 29 cnt++; 30 int now=stack[top--]; 31 cir[now]=1; 32 vis[now]=0; 33 huan[now]=cnt; 34 sum++; 35 while (now!=x) { 36 now=stack[top--]; 37 cir[now]=1; 38 vis[now]=0; 39 huan[now]=cnt; 40 sum++; 41 } 42 summ[cnt]=sum; 43 } 44 } 45 46 int dfs(int x) { 47 if (f[x]) return f[x]; 48 if (next[x]==x) { 49 f[x]=1; 50 return f[x]; 51 } 52 if (cir[x]) { 53 f[x]=summ[huan[x]]; 54 return f[x]; 55 } 56 if (cir[next[x]]) { 57 f[x]=summ[huan[next[x]]]+1; 58 return f[x]; 59 } 60 f[x]=dfs(next[x])+1; 61 return f[x]; 62 } 63 64 int main() { 65 scanf("%d",&n); 66 for (int i=1; i<=n; i++) { 67 int x; 68 scanf("%d",&x); 69 next[i]=x; 70 if (x!=i) add(i,x);//其實這裏沒有必要建邊,用next數組便可。 71 } 72 for (int i=1; i<=n; i++) 73 if (!dfn[i]) tarjan(i);//tarjan縮點 74 for (int i=1; i<=n; i++) if (summ[huan[i]]==1) cir[i]=0; 75 //for (int i=1; i<=n; i++) printf("%d\n",cir[i]); 76 for (int i=1; i<=n; i++) printf("%d\n",dfs(i));//記憶化搜索 77 return 0; 78 }