BZOJ1123 [POI2008]BLO

tarjan求割点,乘法原理统计答案,对数答案翻倍。

By:大奕哥

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=100005;
 4 struct node{
 5     int to,nex;
 6 }e[1000005];
 7 int head[N],dfn[N],low[N],size[N],idx,cnt,n,m;
 8 long long ans[N];
 9 void add(int x,int y)
10 {
11     e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt;
12 }
13 void dfs(int x,int fa)
14 {
15     dfn[x]=low[x]=++idx;size[x]=1;int num=0;
16     for(int i=head[x];i;i=e[i].nex)
17     {
18         int y=e[i].to;
19         if(y==fa)continue;
20         if(!dfn[y])
21         {
22             dfs(y,x);
23             size[x]+=size[y];
24             low[x]=min(low[x],low[y]);
25             if(low[y]>=dfn[x])
26             {
27                 ans[x]+=1ll*num*size[y];
28                 num+=size[y];
29             }
30         }
31         else if(size[y])low[x]=min(low[x],dfn[y]);
32     }
33     ans[x]+=1ll*num*(n-num-1);ans[x]+=n-1;
34 }
35 int main()
36 {
37     scanf("%d%d",&n,&m);
38     for(int i=1;i<=m;++i)
39     {
40         int x,y;
41         scanf("%d%d",&x,&y);
42         add(x,y);add(y,x);
43     }
44     for(int i=1;i<=n;++i)
45     if(!dfn[i])dfs(i,i);
46     for(int i=1;i<=n;++i)
47     printf("%lld
",ans[i]*2);
48     return 0;
49 }
原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8442995.html