1123: [POI2008]BLO
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 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
1 2
2 3
1 3
3 4
4 5
Sample Output
8
8
16
14
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
但是确定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 ",(ans[i]+n-1)*2); 33 }