[POI2008]BLO

1123: [POI2008]BLO

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1519  Solved: 697
[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
 
 
把有序对转化成无序对,然后跑个tarjan的求割点算法就OJBK了。
 
 
#include<bits/stdc++.h>
#define ll long long
const int maxn=100005;
using namespace std;
int hd[maxn],to[maxn*10],ne[maxn*10];
int n,m,siz[maxn],dfn[maxn],low[maxn],dc=0;
ll ans[maxn];

inline int read(){
	int x=0; char ch=getchar();
	for(;!isdigit(ch);ch=getchar());
	for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
	return x;
}

void dfs(int x){
	low[x]=dfn[x]=++dc;
	siz[x]=1;
	int alr=0;
	for(int i=hd[x];i;i=ne[i])
	    if(!dfn[to[i]]){
	    	dfs(to[i]),siz[x]+=siz[to[i]];
	    	low[x]=min(low[x],low[to[i]]);
	    	if(low[to[i]]>=dfn[x]) ans[x]+=siz[to[i]]*(ll)alr,alr+=siz[to[i]];
		}
		else low[x]=min(low[x],dfn[to[i]]);
	ans[x]+=alr*(ll)(n-alr-1);
}

int main(){
	n=read(),m=read();
	int uu,vv;
	for(int i=1;i<=m;i++){
		uu=read(),vv=read();
		to[i]=vv,ne[i]=hd[uu],hd[uu]=i;
		to[i+m]=uu,ne[i+m]=hd[vv],hd[vv]=i+m;
	}
	fill(ans+1,ans+n+1,n-1);
	dfs(1);
	for(int i=1;i<=n;i++) printf("%lld\n",ans[i]<<1);
	return 0;
} 

 

posted @ 2018-03-20 09:37  蒟蒻JHY  阅读(260)  评论(0编辑  收藏  举报