bzoj 1123 [POI2008]BLO Tarjan求割点

[POI2008]BLO

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1540  Solved: 711
[Submit][Status][Discuss]

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

HINT

 

题解:这道题目看着就比较水,只有割点的时候才会有结果。

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<vector>
 8 
 9 #define N 100007
10 #define M 500007
11 #define ll long long
12 using namespace std;
13 inline int read()
14 {
15     int x=0,f=1;char ch=getchar();
16     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
17     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 
21 int n,m;
22 ll ans[N];
23 int tim,dfn[N],low[N],siz[N];
24 int cnt,hed[N],rea[M<<1],nxt[M<<1];
25 
26 void add(int u,int v)
27 {
28     nxt[++cnt]=hed[u];
29     hed[u]=cnt;
30     rea[cnt]=v;
31 }
32 void add_two_way(int u,int v)
33 {
34     add(u,v);
35     add(v,u);
36 }
37 void Tarjan(int u)
38 {
39     ll res=0;
40     siz[u]=1,dfn[u]=low[u]=++tim;
41     for (int i=hed[u];i!=-1;i=nxt[i])
42     {
43         int v=rea[i];
44         if (dfn[v]) low[u]=min(low[u],dfn[v]);
45         else
46         {
47             Tarjan(v);
48             siz[u]+=siz[v];
49             low[u]=min(low[u],low[v]);
50             if (dfn[u]<=low[v])
51             {
52                 ans[u]+=res*siz[v];
53                 res+=siz[v];
54             }
55         }
56     }
57     ans[u]+=res*(n-res-1);//不然res是0 
58 }
59 #undef N
60 #undef M
61 int main()
62 {
63     memset(hed,-1,sizeof(hed));
64     n=read(),m=read();
65     for (int i=1;i<=m;i++)
66         add_two_way(read(),read());
67     Tarjan(1);
68     for (int i=1;i<=n;i++)
69         printf("%lld\n",(ans[i]+n-1)*2);
70 }

 

posted @ 2018-04-14 20:01  Kaiser-  阅读(143)  评论(0编辑  收藏  举报