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\n",ans[i][1]);
63         else
64             printf("\n");
65     }
66     return 0;
67 }

原文地址:https://www.cnblogs.com/iat14/p/12252812.html

时间: 2024-10-31 19:13:30

ICPC2019徐州 现场赛M Kill the tree 树的重心的相关文章

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

问因数<3的数个数,是否小于给定区间1/3.因数<3除了1以外等价于素数. 据说杜教筛改成求素数前缀和的版本可以暴力做,但是并不会. 我们一个直观感受是,素数是越来越稀疏的,打表发现,50以外长度30以上,一定满足.而长度不到30的,用根号算法暴力判断每个元素即可. 注意要以乘代除,或者起码除double...... 1 #include <cstdio> 2 #include <cmath> 3 using namespace std; 4 int T,l,r; 5

2018徐州现场赛A

题目链接:http://codeforces.com/gym/102012/problem/A 题目给出的算法是通过异或和位移 , 每次生成不同的32位, 周期为2的32次方减1.题目的总边数太少,跑不出重边,所以有最小生成树的话就只有一个 #include<iostream> #include<algorithm> using namespace std; unsigned long long k1,k2; #define inf 0x3f3f3f3f #define mod 1

13杭州区域赛现场赛Rabbit Kingdom(树状数组+离线)

题意:给你一个长度数列,再给你m个询问(一个区间),问你在这个区间里面有多少个数与其他的数都互质. 解题思路:你看这种类型的题目都可以肯定这是 离线+树状数组(线段树).主要就是他的更新信息.这里我的处理是先把1-200000(每个数的范围)数里面所有的质因子求出来.然后从后往前遍历数组.会出现以下几种情况 1.a[k]的质因子在后面出现过而[更新标记] 和[被更新标记] 都为假 2.a[k]的质因子在后面出现过的那个位置 I   [更新标记]为 真 . 3.a[k]的质因子在后面出现过且那个位

20180909徐州网络赛题解

目录 20180909徐州网络赛题解 A. Hard to prepare MEANING SOLUTION CODE B. BE, GE or NE MEANING SOLUTION CODE F. Features Track CODE G. Trace MENING SOLUTION CODE H. Ryuji doesn't want to study MEANING CODE I. Characters with Hash CODE J. Maze Designer MEANING S

HDU 4821 杭州现场赛:每个片段字符串哈希比较

I - String Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4821 Description Given a string S and two integers L and M, we consider a substring of S as "recoverable" if and only if (i) I

【解题报告】牡丹江现场赛之ABDIK ZOJ 3819 3820 3822 3827 3829

那天在机房做的同步赛,比现场赛要慢了一小时开始,直播那边已经可以看到榜了,所以上来就知道A和I是水题,当时机房电脑出了点问题,就慢了好几分钟,12分钟才A掉第一题... A.Average Score 题目大意:给定A序列和B序列,长度分别是n和m,告诉你A序列中的n-1个数和B序列的m个数,求剩下的那个A序列中的数满足:将这个数从A序列移除,然后添加到B序列,使得A序列的平均值变小,B序列的平均值变大.求这个数的取值范围(是整数) 解题思路:求出A序列剩下的n-1个数的平均值,和B序列的平均值

HDUOJ-------2493Timer(数学 2008北京现场赛H题)

Timer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 445    Accepted Submission(s): 90 Problem Description Recently, some archaeologists discovered an ancient relic on a small island in the Pa

HDU 4791 Alice&#39;s Print Service (2013长沙现场赛,二分)

Alice's Print Service Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1855    Accepted Submission(s): 454 Problem Description Alice is providing print service, while the pricing doesn't seem to

HDU 4791 Alice&#39;s Print Service(2013长沙区域赛现场赛A题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4791 解题报告:打印店提供打印纸张服务,需要收取费用,输入格式是s1 p1 s2 p2 s3 p3...表示打印区间s1到s2张纸的单价是p1,打印区间s2 到s3的单价是p2....最后是sn到无穷大的单价是pn,让你求打印k张纸的总费用最少是多少?有m次查询. 因为s1*p1 > s2 * p2 > s3*p3......,很显然,加入k所在的那个区间是第x个区间,那么最低费用要么是k * p