【BZOJ1123】 [POI2008]BLO (tarjan)
tarjan判断割点...拿掉一个点之后,会被分成若干个联通块,用节点个数和统计一下他们相互不能到达的个数就好。
1 const maxn=100419; 2 maxm=1000419; 3 type 4 edgetype=record 5 toward,next:longint; 6 end; 7 8 var 9 edge:array[0..maxm] of edgetype; 10 first,dfn,low,stack,s:array[0..maxn] of longint; 11 pd:array[0..maxn] of boolean; 12 sum:array[0..maxn] of int64; 13 tot,cnt,i,n,m:longint; 14 15 function min(x,y:longint):longint; begin if x<y then exit(x) else exit(y); end; 16 17 procedure addedge(i,j:longint); 18 begin 19 inc(tot); 20 edge[tot].toward:=j; 21 edge[tot].next:=first[i]; 22 first[i]:=tot; 23 end; 24 25 procedure add(i,j:longint); 26 begin 27 addedge(i,j); addedge(j,i); 28 end; 29 30 procedure tarjan(v:longint); 31 var i,tmp,son:longint; 32 begin 33 son:=0; 34 inc(cnt); dfn[v]:=cnt; low[v]:=cnt; 35 pd[v]:=true; s[v]:=1; 36 i:=first[v]; 37 while i<>0 do 38 begin 39 tmp:=edge[i].toward; 40 if dfn[tmp]=0 then 41 begin 42 tarjan(tmp); 43 s[v]:=s[v]+s[tmp]; 44 low[v]:=min(low[v],low[tmp]); 45 if dfn[v]<=low[tmp] then 46 begin 47 sum[v]:=sum[v]+int64(son)*s[tmp]; 48 inc(son,s[tmp]); 49 end; 50 end 51 else low[v]:=min(dfn[tmp],low[v]); 52 i:=edge[i].next; 53 end; 54 sum[v]:=sum[v]+int64(son)*(n-son-1); 55 end; 56 57 procedure init; 58 var i,a,b:longint; 59 begin 60 readln(n,m); 61 for i:= 1 to m do 62 begin 63 readln(a,b); 64 add(a,b); 65 end; 66 tarjan(1); 67 end; 68 69 Begin 70 init; 71 for i:= 1 to n do writeln((sum[i]+n-1)<<1); 72 End.