1. 程式人生 > >BZOJ1123 [POI2008]BLO

BZOJ1123 [POI2008]BLO

+= long bzoj1123 names 割點 mes head std ans

tarjan求割點,乘法原理統計答案,對數答案翻倍。

By:大奕哥

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=100005;
 4 struct node{
 5     int to,nex;
 6 }e[1000005];
 7 int head[N],dfn[N],low[N],size[N],idx,cnt,n,m;
 8 long long ans[N];
 9 void add(int x,int y)
10 {
11     e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt;
12 } 13 void dfs(int x,int fa) 14 { 15 dfn[x]=low[x]=++idx;size[x]=1;int num=0; 16 for(int i=head[x];i;i=e[i].nex) 17 { 18 int y=e[i].to; 19 if(y==fa)continue; 20 if(!dfn[y]) 21 { 22 dfs(y,x); 23 size[x]+=size[y]; 24 low[x]=min(low[x],low[y]);
25 if(low[y]>=dfn[x]) 26 { 27 ans[x]+=1ll*num*size[y]; 28 num+=size[y]; 29 } 30 } 31 else if(size[y])low[x]=min(low[x],dfn[y]); 32 } 33 ans[x]+=1ll*num*(n-num-1);ans[x]+=n-1; 34 } 35 int main() 36
{ 37 scanf("%d%d",&n,&m); 38 for(int i=1;i<=m;++i) 39 { 40 int x,y; 41 scanf("%d%d",&x,&y); 42 add(x,y);add(y,x); 43 } 44 for(int i=1;i<=n;++i) 45 if(!dfn[i])dfs(i,i); 46 for(int i=1;i<=n;++i) 47 printf("%lld\n",ans[i]*2); 48 return 0; 49 }

BZOJ1123 [POI2008]BLO