bzoj 1123 BLO
转载请注明出处:
http://www.cnblogs.com/hzoi-wangxh/p/7738615.html
1123: [POI2008]BLO
Description
Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通。
Input
输入n<=100000 m<=500000及m条边
Output
输出n个数,代表如果把第i个点去掉,将有多少对点不能互通。
Sample Input
5 5
1 2
2 3
1 3
3 4
4 5
Sample Output
8
8
16
14
8
题解:
其实就是个tarjan求点双。
点双并不用实际求出来,只是在搜索树中传上去,遇到割点求一下即可。
注意(x,y)和(y,x)是不同对点。
附上代码:
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cstdio> 5 #include<algorithm> 6 #include<cmath> 7 using namespace std; 8 #define int long long 9 #define mmin(a,b) (a<b?a:b) 10 struct tree{ 11 int u,v,next; 12 }l[1001000]; 13 int n,m,lian[101000],e,ans[101000]; 14 int dfn[101000],low[101000],num,size[101000]; 15 void bian(int,int); 16 void tar(int); 17 signed main() 18 { 19 // freopen("in.txt","r",stdin); 20 scanf("%lld%lld",&n,&m); 21 for(int i=1;i<=m;i++) 22 { 23 int x,y; 24 scanf("%lld%lld",&x,&y); 25 bian(x,y); 26 bian(y,x); 27 } 28 tar(1); 29 for(int i=1;i<=n;i++) printf("%lld\n",ans[i]+2*n-2); 30 // while(1); 31 return 0; 32 } 33 void bian(int x,int y) 34 { 35 e++; 36 l[e].u=x; 37 l[e].v=y; 38 l[e].next=lian[x]; 39 lian[x]=e; 40 } 41 void tar(int x) 42 { 43 dfn[x]=low[x]=++num; 44 size[x]=1; 45 int zz=0; 46 for(int i=lian[x];i;i=l[i].next) 47 { 48 int v=l[i].v; 49 if(dfn[v]==0) 50 { 51 tar(v); 52 size[x]+=size[v]; 53 low[x]=mmin(low[x],low[v]); 54 if(dfn[x]<=low[v]) 55 { 56 ans[x]+=zz*size[v]*2ll; 57 zz+=size[v]; 58 } 59 } 60 else 61 low[x]=mmin(dfn[v],low[x]); 62 } 63 ans[x]+=zz*(n-zz-1)*2ll; 64 }