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 }
View Code

 

posted @ 2017-10-19 21:24  hzoi_wangxh  阅读(339)  评论(0编辑  收藏  举报