题目描述 Description
阿米巴是小强的好朋友。
阿米巴和小强在草原上捉蚂蚱。小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难。
学过生物的阿米巴告诉小强,草原是一个极其稳定的生态系统。如果蚂蚱灭绝了,小鸟照样可以吃别的虫子,所以一个物种的灭绝并不一定会引发重大的灾难。
我们现在从专业一点的角度来看这个问题。我们用一种叫做食物网的有向图来描述生物之间的关系:
一个食物网有N个点,代表N种生物,如果生物x可以吃生物y,那么从y向x连一个有向边。
这个图没有环。
图中有一些点没有连出边,这些点代表的生物都是生产者,可以通过光合作用来生存; 而有连出边的点代表的都是消费者,它们必须通过吃其他生物来生存。
如果某个消费者的所有食物都灭绝了,它会跟着灭绝。
我们定义一个生物在食物网中的“灾难值”为,如果它突然灭绝,那么会跟着一起灭绝的生物的种数。
举个例子:在一个草场上,生物之间的关系是:
如果小强和阿米巴把草原上所有的羊都给吓死了,那么狼会因为没有食物而灭绝,而小强和阿米巴可以通过吃牛、牛可以通过吃草来生存下去。所以,羊的灾难值是1。但是,如果草突然灭绝,那么整个草原上的5种生物都无法幸免,所以,草的灾难值是4。
给定一个食物网,你要求出每个生物的灾难值。
输入描述 Input Description
第一行是一个正整数N,表示生物的种数。生物从1标号到N。
接下来N行,每行描述了一个生物可以吃的其他生物的列表,格式为用空格隔开的若干个数字,每个数字表示一种生物的标号,最后一个数字是0表示列表的结束。
输出描述 Output Description
包含N行,每行一个整数,表示每个生物的灾难值
样例输入 Sample Input
5
0
1 0
1 0
2 3 0
2 0
样例输出 Sample Output
4
1
0
0
0
数据范围及提示 Data Size & Hint
对50%的数据,N ≤ 10000。
对100%的数据,1 ≤ N ≤ 65534。
输入文件的大小不超过1M。保证输入的食物网没有环。
对于一个点i,他的死亡应该被一系列点影响(就是j死了i就会死),这些点就是这个点i往下走的必经之点
这些点构成一条链,所以可以用前缀和的思想来累加,所以我们只要求出这个点链的next是什么
所以现在关键是求这next
然后我就用了lca来求next
每个点向他的next连一条边,一个点的next就是他的儿子的最近公共祖先
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 const 2 maxn=66000; 3 maxm=1000000; 4 var 5 d,ans,first,dep:array[0..maxn]of longint; 6 last,next:array[0..maxm]of longint; 7 f:array[0..maxn,0..100]of longint; 8 n,tot:longint; 9 10 procedure insert(x,y:longint); 11 begin 12 inc(d[y]); 13 inc(tot); 14 last[tot]:=y; 15 next[tot]:=first[x]; 16 first[x]:=tot; 17 end; 18 19 var 20 q:array[0..maxn]of longint; 21 l,r:longint; 22 23 procedure init; 24 var 25 i,x:longint; 26 begin 27 read(n); 28 for i:=1 to n do 29 begin 30 read(x); 31 while x<>0 do 32 begin 33 insert(i,x); 34 read(x); 35 end; 36 end; 37 l:=1; 38 for i:=1 to n do 39 if d[i]=0 then 40 begin 41 inc(r); 42 q[r]:=i; 43 end; 44 end; 45 46 procedure new(x:longint); 47 var 48 i:longint; 49 begin 50 i:=0; 51 while f[x,i]<>0 do 52 begin 53 f[x,i+1]:=f[f[x,i],i]; 54 inc(i); 55 end; 56 end; 57 58 procedure swap(var x,y:longint); 59 var 60 t:longint; 61 begin 62 t:=x;x:=y;y:=t; 63 end; 64 65 function lca(x,y:longint):longint; 66 var 67 k:longint; 68 begin 69 if dep[x]<dep[y] then swap(x,y); 70 while dep[x]>dep[y] do 71 x:=f[x,trunc(ln(dep[x]-dep[y])/ln(2))]; 72 if x=y then exit(x); 73 while f[x,0]<>f[y,0] do 74 begin 75 k:=0; 76 while f[x,k+1]<>f[y,k+1] do 77 inc(k); 78 x:=f[x,k]; 79 y:=f[y,k]; 80 end; 81 exit(f[x,0]); 82 end; 83 84 procedure work; 85 var 86 i,j,t:longint; 87 begin 88 while l<=r do 89 begin 90 for i:=l to r do 91 begin 92 j:=first[q[i]]; 93 while j<>0 do 94 begin 95 dec(d[last[j]]); 96 if d[last[j]]=0 then 97 begin 98 inc(r); 99 q[r]:=last[j]; 100 end; 101 j:=next[j]; 102 end; 103 end; 104 l:=i+1; 105 end; 106 for i:=n downto 1 do 107 begin 108 j:=first[q[i]]; 109 t:=last[j]; 110 j:=next[j]; 111 while j<>0 do 112 begin 113 t:=lca(t,last[j]); 114 j:=next[j]; 115 end; 116 f[q[i],0]:=t; 117 dep[q[i]]:=dep[t]+1; 118 new(q[i]); 119 end; 120 for i:=1 to n do 121 inc(ans[f[q[i],0]],ans[q[i]]+1); 122 for i:=1 to n do 123 writeln(ans[i]); 124 end; 125 126 begin 127 init; 128 work; 129 end.