每一年,在威斯康星州,奶牛們都會穿上衣服,收集農夫約翰在N(1<=N<=100,000)個牛棚隔間中留下的糖果,以此來慶祝美國秋天的萬聖節。ios
因爲牛棚不太大,FJ經過指定奶牛必須遵循的穿越路線來確保奶牛的樂趣。爲了實現這個讓奶牛在牛棚裏來回穿梭的方案,FJ在第i號隔間上張貼了一個「下一個隔間」Next_i(1<=Next_i<=N),告訴奶牛要去的下一個隔間;這樣,爲了收集它們的糖果,奶牛就會在牛棚裏來回穿梭了。post
FJ命令奶牛i應該從i號隔間開始收集糖果。若是一隻奶牛回到某一個她已經去過的隔間,她就會中止收集糖果。this
在被迫中止收集糖果以前,計算一下每頭奶牛要前往的隔間數(包含起點)。spa
第1行 整數n。翻譯
第2行到n+1行 每行包含一個整數 next_i 。code
n行,第i行包含一個整數,表示第i只奶牛要前往的隔間數。blog
有4個隔間內存
隔間1要求牛到隔間1ci
隔間2要求牛到隔間3it
隔間3要求牛到隔間2
隔間4要求牛到隔間3
牛1,從1號隔間出發,總共訪問1個隔間;
牛2,從2號隔間出發,而後到三號隔間,而後到2號隔間,終止,總共訪問2個隔間;
牛3,從3號隔間出發,而後到2號隔間,而後到3號隔間,終止,總共訪問2個隔間;
牛4,從4號隔間出發,而後到3號隔間,而後到2號隔間,而後到3號隔間,終止,總共訪問3個隔間。
翻譯提供者:吃葡萄吐糖
Every year in Wisconsin the cows celebrate the USA autumn holiday of Halloween by dressing up in costumes and collecting candy that Farmer John leaves in the N (1 <= N <= 100,000) stalls conveniently numbered 1..N.
Because the barn is not so large, FJ makes sure the cows extend their fun by specifying a traversal route the cows must follow. To implement this scheme for traveling back and forth through the barn, FJ has posted a 'next stall number' next_i (1 <= next_i <= N) on stall i that tells the cows which stall to visit next; the cows thus might travel the length of the barn many times in order to collect their candy.
FJ mandates that cow i should start collecting candy at stall i. A cow stops her candy collection if she arrives back at any stall she has already visited.
Calculate the number of unique stalls each cow visits before being forced to stop her candy collection.
POINTS: 100
每一年萬聖節,威斯康星的奶牛們都要打扮一番,出門在農場的N個牛棚裏轉 悠,來採集糖果.她們每走到一個不曾通過的牛棚,就會採集這個棚裏的1顆糖果.
農場不大,因此約翰要想盡法子讓奶牛們獲得快樂.他給每個牛棚設置了一個「後繼牛 棚」.牛棚i的後繼牛棚是next_i 他告訴奶牛們,她們到了一個牛棚以後,只要再日後繼牛棚走去, 就能夠蒐集到不少糖果.事實上這是一種有點欺騙意味的手段,來節約他的糖果.
第i只奶牛從牛棚i開始她的旅程.請你計算,每一隻奶牛能夠採集到多少糖果.
輸入格式:
* Line 1: A single integer: N
* Lines 2..N+1: Line i+1 contains a single integer: next_i
輸出格式:
* Lines 1..N: Line i contains a single integer that is the total number of unique stalls visited by cow i before she returns to a stall she has previously visited.
Four stalls.
* Stall 1 directs the cow back to stall 1.
* Stall 2 directs the cow to stall 3
* Stall 3 directs the cow to stall 2
* Stall 4 directs the cow to stall 3
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。求每一個點沿出邊走多遠會走到走過的點。
由於出度爲1,因此狀況就不多了:一個點要麼在環上,要麼在一條通往環的鏈上。
因此咱們用tarjan求出環和環的大小,對於在環上的點,距離就是環的大小;
而後再對每個不在環上的點記搜,距離爲它到環的距離+環的大小。
注意一下邊界就行了。
1 /* 2 qwerta 3 P2921 [USACO08DEC]在農場萬聖節Trick or Treat on the Farm Accepted 4 100 5 代碼 C++,0.93KB 6 提交時間 2018-10-22 21:07:08 7 耗時/內存 670ms, 6144KB 8 */ 9 #include<iostream> 10 #include<cstdio> 11 #include<cmath> 12 using namespace std; 13 int nxt[100003]; 14 int dfn[100003],low[100003],col[100003],ans[100003]; 15 int stack[100003]; 16 bool instack[100003]; 17 int tos=0,tot=0,color=0; 18 void tarjan(int x) 19 { 20 dfn[x]=low[x]=++tot; 21 stack[++tos]=x; 22 instack[x]=1; 23 { 24 if(!dfn[nxt[x]]){tarjan(nxt[x]);low[x]=min(low[x],low[nxt[x]]);} 25 else if(instack[nxt[x]])low[x]=min(low[x],dfn[nxt[x]]); 26 } 27 if(low[x]==dfn[x]) 28 { 29 color++; 30 int j,len=0; 31 do{j=stack[tos--];instack[j]=0; 32 col[j]=color;len++;}while(j!=x); 33 ans[color]=len; 34 } 35 } 36 int dfs(int x) 37 { 38 if(x==nxt[x])return 1; 39 if(ans[col[x]]>1)return ans[col[x]]; 40 return ans[col[x]]=dfs(nxt[x])+1; 41 } 42 int main() 43 { 44 //freopen("a.in","r",stdin); 45 int n; 46 scanf("%d",&n); 47 for(int i=1;i<=n;++i) 48 scanf("%d",&nxt[i]); 49 for(int i=1;i<=n;++i) 50 if(!dfn[i]){tarjan(i);} 51 for(int i=1;i<=n;++i) 52 if(ans[col[i]]==1) 53 { 54 dfs(i); 55 } 56 for(int i=1;i<=n;++i) 57 cout<<ans[col[i]]<<endl; 58 return 0; 59 }