『Balancing Act 树的重心』
<更新提示>
<第一次更新>
<正文>
树的重心
我们先来认识一下树的重心。
树的重心也叫树的质心。找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡。
根据树的重心的定义,我们可以通过树形DP来求解树的重心。
设\(Max_i\)代表删去i节点后树中剩下子树中节点最多的一个子树的节点数。由于删去节点i至少将原树分为两部分,所以满足\(\ \frac{1}{2}n \leq Max_i\),我们要求的就是一个\(i\),使得\(Max_i\)最小。
对于Max数组,我们可以列出如下状态转移方程:
\]
size数组即为节点个数(树的大小),可以在树形DP中顺带求解。
\(Code:\)
inline void dp(int r,int f)
{
size[r]=1;
for(int i=0;i<Link[r].size();i++)
{
int Son=Link[r][i];
if(Son==f)continue;
dp(Son,r);
size[r]+=size[Son];
Max[r]=max(Max[r],size[Son]);
}
Max[r]=max(Max[r],n-size[r]);
if(Max[r]==Max[ans]&&r<ans)ans=r;
if(Max[r]<Max[ans])ans=r;
}
还是通过一道例题来认识一下。
Balancing Act(POJ1655)
Description
The city consists of intersections and streets that connect them.
Heavy snow covered the city so the mayor Milan gave to the winter-service a list of streets that have to be cleaned of snow. These streets are chosen such that the number of streets is as small as possible but still every two intersections to be connected i.e. between every two intersections there will be exactly one path. The winter service consists of two snow plovers and two drivers, Mirko and Slavko, and their starting position is on one of the intersections.
The snow plover burns one liter of fuel per meter (even if it is driving through a street that has already been cleared of snow) and it has to clean all streets from the list in such order so the total fuel spent is minimal. When all the streets are cleared of snow, the snow plovers are parked on the last intersection they visited. Mirko and Slavko don’t have to finish their plowing on the same intersection.
Write a program that calculates the total amount of fuel that the snow plovers will spend.
Input Format
The first line of the input contains two integers: N and S, 1 <= N <= 100000, 1 <= S <= N. N is the total number of intersections; S is ordinal number of the snow plovers starting intersection. Intersections are marked with numbers 1...N.
Each of the next N-1 lines contains three integers: A, B and C, meaning that intersections A and B are directly connected by a street and that street's length is C meters, 1 <= C <= 1000.
Output Format
Write to the output the minimal amount of fuel needed to clean all streets.
Sample Input
5 2
1 2 1
2 3 2
3 4 2
4 5 1
Sample Output
6
解析
这个就是树的重心的模板题了嘛。
还有题目的第二问就是重心子树中节点数最多的子树的节点数。嗯!刚好符合我们Max数组的定义,直接输出就可以了。
\(Code:\)
#include<cstdio>
#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
#define mset(name,val) memset(name,val,sizeof name)
using namespace std;
const int N=20000+50;
int n,size[N],Max[N],ans,cnt;
vector < int > Link[N];
inline void input(void)
{
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
Link[x].push_back(y);
Link[y].push_back(x);
}
}
inline void dp(int r,int f)
{
size[r]=1;
for(int i=0;i<Link[r].size();i++)
{
int Son=Link[r][i];
if(Son==f)continue;
dp(Son,r);
size[r]+=size[Son];
Max[r]=max(Max[r],size[Son]);
}
Max[r]=max(Max[r],n-size[r]);
if(Max[r]==Max[ans]&&r<ans)ans=r;
if(Max[r]<Max[ans])ans=r;
}
int main(void)
{
int T;
scanf("%d",&T);
while(T--)
{
mset(Max,0x00);
mset(size,0x00);
ans=0;cnt=0;Max[0]=0x3f3f3f3f;
input();
dp(1,0);
printf("%d %d\n",ans,Max[ans]);
for(int i=1;i<=n;i++)
Link[i].clear();
}
}
<后记>
『Balancing Act 树的重心』的更多相关文章
- POJ 1655 Balancing Act 树的重心
Balancing Act Description Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. ...
- POJ1655 Balancing Act(树的重心)
题目链接 Balancing Act 就是求一棵树的重心,然后统计答案. #include <bits/stdc++.h> using namespace std; #define REP ...
- poj-1655 Balancing Act(树的重心+树形dp)
题目链接: Balancing Act Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11845 Accepted: 4 ...
- PKU 1655 Balancing Act(树+树的重心)
#include<cstdio> #include<cstring> #include<algorithm> #define maxn 20005 using na ...
- 『左偏树 Leftist Tree』
新增一道例题 左偏树 Leftist Tree 这是一个由堆(优先队列)推广而来的神奇数据结构,我们先来了解一下它. 简单的来说,左偏树可以实现一般堆的所有功能,如查询最值,删除堆顶元素,加入新元素等 ...
- POJ 1655 - Balancing Act 树型DP
这题和POJ 3107 - Godfather异曲同工...http://blog.csdn.net/kk303/article/details/9387251 Program: #include&l ...
- poj1655 Balancing Act 找树的重心
http://poj.org/problem? id=1655 Balancing Act Time Limit: 1000MS Memory Limit: 65536K Total Submis ...
- POJ 1655 Balancing Act【树的重心】
Balancing Act Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14251 Accepted: 6027 De ...
- POJ 1655.Balancing Act 树形dp 树的重心
Balancing Act Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14550 Accepted: 6173 De ...
随机推荐
- 浅析Kubernetes的工作原理
先放一张Kubernetes的架构图: 整体来看,是一个老大,多个干活的这种结构,基本上所有的分布式系统都是这样,但是里面的组件名称就纷繁复杂,下面将一一解析. 1.元数据存储与集群维护 作为一个集群 ...
- 如何在Ubuntu 18.04中安装VMware Workstation Player
参考链接 如何在Ubuntu 18.04中安装VMware Workstation Player https://www.sysgeek.cn/ubuntu-18-04-install-vmware- ...
- POJ 1966 Cable TV Network (点连通度)【最小割】
<题目链接> 题目大意: 给定一个无向图,求点连通度,即最少去掉多少个点使得图不连通. 解题分析: 解决点连通度和边连通度的一类方法总结见 >>> 本题是求点连通度, ...
- less 命令翻页键
less 是linux快速浏览文件的命令(防止 误修改文件) less主要就是 浏览文件 查找文件 浏览文件涉及到的就是上下翻页 具体翻页的按键如下表 less 向上翻页 向下翻页 一页 b (ba ...
- pyenv global 设置失败 pyenv local 设置就成功了 不知道啥原因
dev@PC-20190309QPVT:/mnt/c/data/htdocs/python/flaskr$ pyenv global 3.6.1dev@PC-20190309QPVT:/mnt/c/d ...
- Linux指令集
最近在学习Linux虚拟机,下面是我在学习虚拟机的过程中使用过的一些指令,及其作用. pwd-> 列出当前目录路径 ls-> 列出当前目录列表 cd-> 改变目录 mkdir-> ...
- input标签实现小数点后两位保留小数
短短一行代码就可以实现 <input type="number" min="0" max="100" step="0.01& ...
- javascript是什么,可以做什么?
是一门脚本语言:不需要编译,直接运行 是一门解释型语言:遇到一行代码就解释一行代码 是一门动态类型的语言 是一门基于对象的语言 是一门弱类型的语言:声明变量的时候不用特别声明类型都使用var 不是一门 ...
- CSS矩形、三角形等
1.圆形 CSS代码如下:宽高一样,border-radius设为宽高的一半 #circle { width: 100px; height: 100px; background: red; -moz- ...
- js将一个具有相同键值对的一维数组转换成二维数组
这两天,一个前端朋友在面试的笔试过程中遇到了一道类似于"用js实现将一个具有相同code值的一维数组转换成相同code值在一起的二维数组"的题目.他面试过后,把这个问题抛给了我,问 ...