bzoj1123: [POI2008]BLO

1123: [POI2008]BLO

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1002  Solved: 422
[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
 
 
by http://blog.csdn.net/qq_18455665/article/details/50968307
在Tarjan中如果搜到的点的low[v]< deep[u]说明没法形成强连通分量就要在ans[u]中加上每两块的size的乘积 
但是确定u是割点了以后,它deep比它深的连通块和deep比它浅的不连通,所以ans[u]+=c*(n-c-1) 
删去后其它和u也不连通所以加上n-1再乘2
 1 #include<bits/stdc++.h>
 2 #define rep(i,l,r) for(int i=l;i<=r;++i)
 3 using namespace std;
 4 const int N=1002333;
 5 int head[N],tot,a,b,n,m,low[N],dfn[N],sz[N],cnt;
 6 typedef long long ll;
 7 ll ans[N];
 8 struct zs{
 9     int to,next;
10 }e[N];
11 inline void ins(int u,int v){
12     e[++tot].to=v; e[tot].next=head[u]; head[u]=tot;
13 }
14 void dfs(int x){
15     int t=0;
16     sz[x]=1; dfn[x]=low[x]=++cnt;
17     for(int k=head[x];k;k=e[k].next) if(dfn[e[k].to]) low[x]=min(low[x],dfn[e[k].to]);else {
18         dfs(e[k].to);
19         sz[x]+=sz[e[k].to];
20         low[x]=min(low[x],low[e[k].to]);
21         if(dfn[x]<=low[e[k].to]){
22             ans[x]+=(ll)t*sz[e[k].to];
23             t+=sz[e[k].to];
24         }
25     }
26     ans[x]+=(ll)t*(n-t-1);
27 }
28 int main(){
29     scanf("%d%d",&n,&m);
30     rep(i,1,m) scanf("%d%d",&a,&b),ins(a,b),ins(b,a);
31     dfs(1);
32     rep(i,1,n) printf("%lld\n",(ans[i]+n-1)*2);
33 }
View Code

 

posted @ 2016-10-23 21:23  Bloodline  阅读(236)  评论(0编辑  收藏  举报