1123: [POI2008]BLO
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1561 Solved: 728
[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
HINT
Source
在tarjin求割点的同时,维护一下不联通的对数和,最后不要忘了,在点i删去后i和其他n-1个点也不连通
#include <bits/stdc++.h>
#define ll long long
#define inf 1e9+10
using namespace std;
inline int read(){
int x=0;int f=1;char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int MAXN=1e6+10;
struct node{
int y,next;
}e[MAXN];
int linkk[MAXN],dfn[MAXN],low[MAXN],dfs_clock,siz[MAXN],m,n,len;
ll ans[MAXN];
inline void insert(int x,int y){
e[++len].y=y;e[len].next=linkk[x];linkk[x]=len;
e[++len].y=x;e[len].next=linkk[y];linkk[y]=len;
}
inline void tarjin(int x){
dfn[x]=low[x]=++dfs_clock;
ll t=0;siz[x]=1;
for(int i=linkk[x];i;i=e[i].next){
if(dfn[e[i].y]) low[x]=min(low[x],dfn[e[i].y]);
else{
tarjin(e[i].y);
low[x]=min(low[x],low[e[i].y]);
siz[x]+=siz[e[i].y];
if(dfn[x]<=low[e[i].y]){
ans[x]+=1LL*t*siz[e[i].y];
t+=siz[e[i].y];
}
}
}
ans[x]+=1LL*t*(n-t-1);
}
int main(){
n=read();m=read();
for(int i=1;i<=m;i++){
int x=read();int y=read();
insert(x,y);
}
tarjin(1);
for(int i=1;i<=n;i++){
printf("%lld\n",(ans[i]+n-1)*2);
}
return 0;
}