1. 程式人生 > >[POI2008]BLO

[POI2008]BLO

log 不能 割點 ans HP 連通 discuss geo limit

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;
} 

[POI2008]BLO