POJ 1655 求树的重心
POJ 1655
【题目链接】POJ 1655
【题目类型】求树的重心
&题意:
定义平衡数为去掉一个点其最大子树的结点个数,求给定树的最小平衡数和对应要删的点。其实就是求树的重心,找到一个点,其所有的子树中最大的子树的节点数最少,那么这个点就是这棵树的重心,删除重心后,剩余的子树更加平衡正好满足题意
&题解:
那么怎么求呢?我们可以求每个顶点的子树,把子树节点最多的赋为b,那么每个顶点都有一个b,最小的b就是树的重心,一颗树只有1个或2个重心。
【时间复杂度】\(O(n)\)
&代码:
#include <map>
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <set>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
#define cle(a,v) memset(a,(v),sizeof(a))
#define fo(i,a,b) for(int i=(a);i<=(b);i++)
#define fd(i,a,b) for(int i=(a);i>=(b);i--)
#define ll long long
const int maxn = 2e4 + 7;
struct Edge {
int v, next;
} edges[maxn * 2];
int tot, head[maxn];
void addedge(int u, int v) {
edges[tot].v = v;
edges[tot].next = head[u];
head[u] = tot++;
}
int n, dp[maxn], an1, an2;
void dfs(int u, int fa) {
int b = 0;
for (int i = head[u]; ~i; i = edges[i].next) {
int v = edges[i].v;
if (v == fa)continue;
dfs(v, u);
dp[u] += dp[v] + 1;
b = max(b, dp[v] + 1);
}
b = max(b, n - dp[u] - 1);
if (an1 > b || an1 == b && an2 > u) {
an1 = b;
an2 = u;
}
}
int main() {
freopen("1.in", "r", stdin);
int t;
scanf("%d", &t);
while (t--) {
tot = 0;
an1 = 1 << 30, an2 = 1 << 30;
cle(head, -1); cle(dp, 0);
scanf("%d", &n);
for (int i = 0; i < n - 1; i++) {
int u, v;
scanf("%d%d", &u, &v);
addedge(u, v);
addedge(v, u);
}
dfs(1, -1);
// fo(i, 1, n) {
// printf("[%d]=%d ", i, dp[i]);
// } printf("\n");
printf("%d %d\n", an2, an1);
}
return 0;
}
POJ 1655 求树的重心的更多相关文章
- poj 1655 找树的重心
树形DP 求树的重心,即选择一个结点删去,使得分出的 若干棵树的结点数 的最大值最小 #include<map> #include<set> #include<cmath ...
- Balancing Act POJ - 1655 (树的重心)
Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any node from the t ...
- poj3107 求树的重心(&& poj1655 同样求树的重心)
题目链接:http://poj.org/problem?id=3107 求树的重心,所谓树的重心就是:在无根树转换为有根树的过程中,去掉根节点之后,剩下的树的最大结点最小,该点即为重心. 剩下的数的 ...
- poj 1655 Balancing Act 求树的重心【树形dp】
poj 1655 Balancing Act 题意:求树的重心且编号数最小 一棵树的重心是指一个结点u,去掉它后剩下的子树结点数最少. (图片来源: PatrickZhou 感谢博主) 看上面的图就好 ...
- POJ 1655 Balancing Act (求树的重心)
求树的重心,直接当模板吧.先看POJ题目就知道重心什么意思了... 重心:删除该节点后最大连通块的节点数目最小 #include<cstdio> #include<cstring&g ...
- POJ 1655 Balancing Act(求树的重心--树形DP)
题意:求树的重心的编号以及重心删除后得到的最大子树的节点个数size,假设size同样就选取编号最小的. 思路:随便选一个点把无根图转化成有根图.dfs一遍就可以dp出答案 //1348K 125MS ...
- POJ 1655 Balancing Act&&POJ 3107 Godfather(树的重心)
树的重心的定义是: 一个点的所有子树中节点数最大的子树节点数最小. 这句话可能说起来比较绕,但是其实想想他的字面意思也就是找到最平衡的那个点. POJ 1655 题目大意: 直接给你一棵树,让你求树的 ...
- 求树的重心(POJ1655)
题意:给出一颗n(n<=2000)个结点的树,删除其中的一个结点,会形成一棵树,或者多棵树,定义删除任意一个结点的平衡度为最大的那棵树的结点个数,问删除哪个结点后,可以让平衡度最小,即求树的重心 ...
- 洛谷P1395 会议(CODEVS.3029.设置位置)(求树的重心)
To 洛谷.1395 会议 To CODEVS.3029 设置位置 题目描述 有一个村庄居住着n个村民,有n-1条路径使得这n个村民的家联通,每条路径的长度都为1.现在村长希望在某个村民家中召开一场会 ...
随机推荐
- 如何写一个Js上传图片插件。
项目里面需要一个上传图片的插件,找了半天没有找到满意的,算了 不找了,自己写一个吧,顺便复习一下js方面的知识.完成之后效果还不错,当然还要继续优化,源码在最后. 介绍一种常见的js插件的写法 ; ( ...
- SAS 对数据的拼接与串接
SAS 对数据的拼接与串接 使用SAS对数据进行串接.合并.更新与修改. 1. 数据集的纵向串接 数据集的纵向串接指的是,将两个或者多个数据集首尾相连,形成 一个新的数据集. 对数据集的纵向串接可以通 ...
- 如何避免OOM
一.减小对象的内存占用 1)使用更加轻量的数据结构 例如,我们可以考虑使用ArrayMap/SparseArray而不是HashMap等传统数据结构. ArrayMap和HashMap主要不同之处在于 ...
- JS AJAX 跨域
原因: 浏览器的同源策略,不允许AJAX 访问 其他接口 协议,域名,端口 一个不同 就跨域了 http 端口(80) https(443) 可以跨域的三个标签: 1. img : 打点统计,没有浏 ...
- 编程菜鸟的日记-初学尝试编程-C++ Primer Plus 第5章编程练习3
#include <iostream>using namespace std;int main(){ double count=0; long double cleo=100; long ...
- SVN 提示clean up 进入死循环
SVN在使用update命令时,提示使用“clean up ”命令,在使用clean up命令时报错“Previous operation has not finished; run 'cleanup ...
- (76)Wangdao.com第十四天_JavaScript 正则表达式对象 RegExp
RegExp Regular Expression,正则表达式是一种表达 文本模式(字符串结构) 的式子. 常常用来按照“给定模式”匹配文本.比如,正则表达式给出一个 Email 地址的模式, ...
- VSCode+Xdebug断点调试PHP(全攻略)
一直都想把php断电调试记录下来,由于拖延症极其严重导致现在才写. 好了,刚去猛喝了几碗心灵鸡汤,趁着这股劲把"Visual Studio Code如何使用XDebug进行php断点调试&q ...
- [LeetCode] Expressive Words 富于表现力的单词
Sometimes people repeat letters to represent extra feeling, such as "hello" -> "he ...
- 蓝桥杯-加法变乘法(java)
蓝桥杯第六届省赛题目-加法变乘法(java) 题目: 我们都知道:1+2+3+ ... + 49 = 1225 现在要求你把其中两个不相邻的加号变成乘号,使得结果为2015 比如: 1+2+3+... ...