BZOJ 1123: [POI2008]BLO

Posted You Siki

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 1123: [POI2008]BLO相关的知识,希望对你有一定的参考价值。

1123: [POI2008]BLO

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1030  Solved: 440
[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

HINT

 

Source

 
[Submit][Status][Discuss]

 

分析

如果一个点不是割点,那么删去后不会对其他点之间的连通性造成影响;如果是一个割点,影响只和其连接的几个块的大小有关。因此Tarjan求割点的同时注意维护子树大小即可。

 

代码

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <iostream>
 6 #include <algorithm>
 7 
 8 using namespace std;
 9 
10 #define N 5000000
11 #define LL long long
12 
13 int n, m; LL ans[N];
14 
15 int hd[N], to[N], nt[N], tot;
16 
17 int dfn[N], low[N], tim;
18 
19 int tarjan(int u, int f)
20 {   
21     dfn[u] = low[u] = ++tim; ans[u] = (n - 1) << 1;
22     
23     int cnt = 0, siz; LL sum = 0, tmp = 0;
24     
25     for (int i = hd[u]; ~i; i = nt[i])if (f != to[i])
26     {
27         if (!dfn[to[i]])
28         {
29             siz = tarjan(to[i], u);
30             low[u] = min(low[u], low[to[i]]);
31             if (low[to[i]] >= dfn[u])
32                 ans[u] += 2LL * siz * sum, sum += siz;
33             else
34                 tmp += siz;
35         }
36         else
37             low[u] = min(low[u], dfn[to[i]]);
38     }
39     
40     ans[u] += 2LL * (n - (sum + 1)) * sum;
41     
42     return sum + tmp + 1;
43 }
44 
45 signed main(void)
46 {
47     scanf("%d%d", &n, &m);
48     
49     memset(hd, -1, sizeof(hd)), tot = 0;
50     
51     for (int i = 1; i <= m; ++i)
52     {
53         int x, y; scanf("%d%d", &x, &y);
54         
55         nt[tot] = hd[x]; to[tot] = y; hd[x] = tot++;
56         nt[tot] = hd[y]; to[tot] = x; hd[y] = tot++;
57     }
58     
59     memset(dfn, 0, sizeof(dfn)); tim = 0; tarjan(1, -1);
60     
61     for (int i = 1; i <= n; ++i)
62         printf("%lld\\n", ans[i]);
63 }
BZOJ_1123.cpp

 

 1 #include <cstdio>
 2 
 3 template <class T>
 4 inline T min(const T &a, const T &b)
 5 {
 6     return a < b ? a : b;
 7 }
 8 
 9 typedef long long lnt;
10 
11 const int mxn = 100005;
12 const int mxm = 1000005;
13 
14 int n, m;
15 
16 int hd[mxn];
17 int to[mxm];
18 int nt[mxm];
19 
20 int dfn[mxn];
21 int low[mxn];
22 
23 lnt ans[mxn];
24 
25 lnt tarjan(int u, int f)
26 {
27     static int tim = 0;
28 
29     ans[u] = (n - 1) << 1;
30     dfn[u] = low[u] = ++tim;
31 
32     lnt siz, sum = 0, tmp = 0;
33 
34     for (int i = hd[u], v; i; i = nt[i])
35         if ((v = to[i]) != f)
36         {
37             if (!dfn[v])
38             {
39                 siz = tarjan(v, u);
40 
41                 low[u] = min(low[u], low[v]);
42 
43                 if (low[v] >= dfn[u])
44                     ans[u] += 2LL * sum * siz, sum += siz;
45                 else
46                     tmp += siz;
47             }
48             else
49                 low[u] = min(low[u], dfn[v]);
50         }
51 
52     ans[u] += 2LL * (n - sum - 1) * sum;
53 
54     return sum + tmp + 1;
55 }
56 
57 signed main(void)
58 {
59     scanf("%d%d", &n, &m);
60 
61     for (int i = 0; i < m; ++i)
62     {
63         static int x, y, tot;
64 
65         scanf("%d%d", &x, &y);
66 
67         nt[++tot] = hd[x], to[tot] = y, hd[x] = tot;
68         nt[++tot] = hd[y], to[tot] = x, hd[y] = tot;
69     }
70 
71     tarjan(1, 0);
72 
73     for (int i = 1; i <= n; ++i)
74         printf("%lld\\n", ans[i]);
75 }

 

@Author: YouSiki

以上是关于BZOJ 1123: [POI2008]BLO的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1123 [POI2008]BLO

bzoj1123: [POI2008]BLO(割点)

1123: [POI2008]BLO

BZOJ-1123BLO Tarjan 点双连通分量

[POI2008]BLO

[POI 2008] BLO