其他分享
首页 > 其他分享> > BZOJ1123 [POI2008]BLO(割点判断 + 点双联通缩点size)

BZOJ1123 [POI2008]BLO(割点判断 + 点双联通缩点size)

作者:互联网

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 typedef long long ll;
 7 const int maxn = 1e5 + 5;
 8 const int maxm = 5e5 + 5;
 9 int dfn[maxn], low[maxn], head[maxn];
10 ll ans[maxn], siz[maxn];
11 int n, m, tot, num, root;
12 bool cut[maxn];
13 struct edge{
14     int to, next;
15 } ed[2*maxm];
16 inline void init(){
17     memset( head, -1, sizeof(head) );
18     memset( dfn, 0, sizeof(dfn) );
19     memset( cut, false, sizeof(cut) );
20     memset( ans, 0, sizeof(ans) );
21     num = 0;
22     tot = 1;
23 }
24 
25 inline int min( int a, int b ){
26     return a<b ? a:b;
27 }
28 
29 inline void add( int u, int v ){
30     tot ++;
31     ed[tot].to = v;
32     ed[tot].next = head[u];
33     head[u] = tot;
34 }
35 
36 inline void tarjan( int u ){
37     dfn[u] = low[u] = ++num;
38     siz[u] = 1;
39     int flag = 0, sum = 0;
40     for( int i=head[u]; i!=-1; i=ed[i].next ){
41         int v = ed[i].to;
42         if( !dfn[v] ){
43             tarjan(v);
44             siz[u] += siz[v];      //计算子树的点个数
45             low[u] = min(low[u], low[v]);
46             if( dfn[u]<=low[v] ){
47                 flag ++;
48                 ans[u] += (ll)siz[v]*(n-siz[v]);    //if(cut[i]) ans = (i的子树, 除该子树的其他部分)的点对和
49                 sum += siz[v];
50                 if( u!=root || flag>1 ) cut[u] = true;
51             }
52         }else low[u] = min(low[u], dfn[v]);
53     }
54     if( cut[u] ) ans[u] += (ll)(n-sum-1)*(sum+1) + (n-1);  //如果去掉的点i是割点ans继续累加上(其他部分,i和i的子树)点对 + (i, 除i的其他部分)点对
55     else ans[u] = 2*(n-1);              //if(!cut[i]) ans = 2*(n-1)
56 }
57 
58 int main(){
59     scanf("%d%d", &n, &m);
60     init();
61     for( int i=0; i<m; i++ ){
62         int u, v;
63         scanf("%d%d", &u, &v);
64         add( u, v );
65         add( v, u );
66     }
67     root = 1;
68     tarjan(1);
69     for( int i=1; i<=n; i++ )
70         printf("%lld\n", ans[i]);
71 
72     return 0;
73 }
74 /*Sample Input
75 5 5
76 1 2
77 2 3
78 1 3
79 3 4
80 4 5
81 Sample Output
82 8
83 8
84 16
85 14
86 8
87 */

 

标签:cut,POI2008,int,memset,割点,BLO,maxn,ans,sizeof
来源: https://www.cnblogs.com/WAautomaton/p/10843920.html