ICPC2019徐州 现场赛M Kill the tree 树的重心

Posted iat14

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ICPC2019徐州 现场赛M Kill the tree 树的重心相关的知识,希望对你有一定的参考价值。

链接

给你一颗以1为根,2^5的树。让你求出以每个点为根的子树中,到子树中每个点距离和最小的点。

首先先做条件转化,到子树中每个点距离和最小,等价于重心,所以问题变成了求每棵子树的重心。

我们考虑如果用子树重心求出父亲的重心。发现一个显而易见的结论,父亲子树的重心,一定在重儿子子树的重心到根的连线上。

我们先做dfs,求出siz和重儿子。然后再做一遍dfs,每次从重儿子的重心往上爬,爬到再爬一步,最大子树会变大为止。这时看下取当前点和其重儿子答案是否相同,如果相同则重心有两个,为当前点和重儿子。否则重心只有一个,为当前点。

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 const int MAXN = 210000;
 5 int n,cnt;
 6 int head[MAXN],siz[MAXN],fa[MAXN],son[MAXN],ans[MAXN][2],to[2 * MAXN],nxt[2 * MAXN];
 7 void dfs1(int x)
 8 {
 9     siz[x] = 1;
10     for (int i = head[x];i;i = nxt[i])
11     {
12         if (to[i] == fa[x])
13             continue;
14         fa[to[i]] = x;
15         dfs1(to[i]);
16         siz[x] += siz[to[i]];
17         if (siz[to[i]] > siz[son[x]])
18             son[x] = to[i];
19     }
20 }
21 void dfs2(int x)
22 {
23     for (int i = head[x];i;i = nxt[i])
24     {
25         if (to[i] == fa[x])
26             continue;
27         dfs2(to[i]);
28     }
29     int t = ans[son[x]][0];
30     if (t == 0)
31         t = x;
32     while (t != x && max(siz[son[t]],siz[x] - siz[t]) >= max(siz[son[fa[t]]],siz[x] - siz[fa[t]]))
33         t = fa[t];
34     ans[x][0] = t;
35     if (max(siz[son[t]],siz[x] - siz[t]) == max(siz[son[son[t]]],siz[x] - siz[son[t]]))
36         ans[x][1] = son[t];
37 }
38 void add(int x,int y)
39 {
40     nxt[++cnt] = head[x];
41     to[cnt] = y;
42     head[x] = cnt;
43 }
44 int main()
45 {
46     scanf("%d",&n);
47     int tx,ty;
48     for (int i = 1;i <= n - 1;i++)
49     {
50         scanf("%d%d",&tx,&ty);
51         add(tx,ty);
52         add(ty,tx); 
53     }
54     dfs1(1);
55     dfs2(1);
56     for (int i = 1;i <= n;i++)
57     {
58         if (ans[i][1] != 0 && ans[i][1] < ans[i][0])
59             swap(ans[i][1],ans[i][0]);
60         printf("%d",ans[i][0]);
61         if (ans[i][1] != 0)
62             printf(" %d
",ans[i][1]);
63         else
64             printf("
");
65     }
66     return 0;
67 }

 

以上是关于ICPC2019徐州 现场赛M Kill the tree 树的重心的主要内容,如果未能解决你的问题,请参考以下文章

2020年2月2日 ICPC2019徐州 现场赛C <3 numbers 思维题

2019ICPC徐州站M题

2019icpc-徐州网络赛

ICPC 2018 徐州赛区网络赛

2018 ICPC 徐州网络赛 D. Easy Math(思维,反演,杜教筛)

2018 ICPC 徐州网络赛 D. Easy Math(思维,反演,杜教筛)