bzoj 1123 [POI2008]BLO Tarjan求割点
[POI2008]BLO
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1540 Solved: 711
[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
题解:这道题目看着就比较水,只有割点的时候才会有结果。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cmath> 7 #include<vector> 8 9 #define N 100007 10 #define M 500007 11 #define ll long long 12 using namespace std; 13 inline int read() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 17 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 18 return x*f; 19 } 20 21 int n,m; 22 ll ans[N]; 23 int tim,dfn[N],low[N],siz[N]; 24 int cnt,hed[N],rea[M<<1],nxt[M<<1]; 25 26 void add(int u,int v) 27 { 28 nxt[++cnt]=hed[u]; 29 hed[u]=cnt; 30 rea[cnt]=v; 31 } 32 void add_two_way(int u,int v) 33 { 34 add(u,v); 35 add(v,u); 36 } 37 void Tarjan(int u) 38 { 39 ll res=0; 40 siz[u]=1,dfn[u]=low[u]=++tim; 41 for (int i=hed[u];i!=-1;i=nxt[i]) 42 { 43 int v=rea[i]; 44 if (dfn[v]) low[u]=min(low[u],dfn[v]); 45 else 46 { 47 Tarjan(v); 48 siz[u]+=siz[v]; 49 low[u]=min(low[u],low[v]); 50 if (dfn[u]<=low[v]) 51 { 52 ans[u]+=res*siz[v]; 53 res+=siz[v]; 54 } 55 } 56 } 57 ans[u]+=res*(n-res-1);//不然res是0 58 } 59 #undef N 60 #undef M 61 int main() 62 { 63 memset(hed,-1,sizeof(hed)); 64 n=read(),m=read(); 65 for (int i=1;i<=m;i++) 66 add_two_way(read(),read()); 67 Tarjan(1); 68 for (int i=1;i<=n;i++) 69 printf("%lld\n",(ans[i]+n-1)*2); 70 }