标签:single iostream 设置 names 答案 integer scada pre other
每年万圣节,威斯康星的奶牛们都要打扮一番,出门在农场的N个牛棚里转 悠,来采集糖果.她们每走到一个未曾经过的牛棚,就会采集这个棚里的1颗糖果.
农场不大,所以约翰要想尽法子让奶牛们得到快乐.他给每一个牛棚设置了一个“后继牛 棚”.牛棚i的后继牛棚是next_i 他告诉奶牛们,她们到了一个牛棚之后,只要再往后继牛棚走去, 就可以搜集到很多糖果.事实上这是一种有点欺骗意味的手段,来节约他的糖果.
第i只奶牛从牛棚i开始她的旅程.请你计算,每一只奶牛可以采集到多少糖果.
输入格式:
Line 1: A single integer: N
输出格式:
4 1 3 2 3
1 2 2 3
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
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 }
[USACO08DEC] Trick or Treat on the Farm
标签:single iostream 设置 names 答案 integer scada pre other
原文地址:http://www.cnblogs.com/zoewilly/p/6018132.html