<更新提示>

<第一次更新>


<正文>

树的重心

我们先来认识一下树的重心。

树的重心也叫树的质心。找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡。

根据树的重心的定义,我们可以通过树形DP来求解树的重心。

设\(Max_i\)代表删去i节点后树中剩下子树中节点最多的一个子树的节点数。由于删去节点i至少将原树分为两部分,所以满足\(\ \frac{1}{2}n \leq Max_i\),我们要求的就是一个\(i\),使得\(Max_i\)最小。

对于Max数组,我们可以列出如下状态转移方程:

\[Max_i=\max_{j\in son(i)}\{size_j,n-size_i\}
\]

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 树的重心』的更多相关文章

  1. POJ 1655 Balancing Act 树的重心

    Balancing Act   Description Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. ...

  2. POJ1655 Balancing Act(树的重心)

    题目链接 Balancing Act 就是求一棵树的重心,然后统计答案. #include <bits/stdc++.h> using namespace std; #define REP ...

  3. poj-1655 Balancing Act(树的重心+树形dp)

    题目链接: Balancing Act Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11845   Accepted: 4 ...

  4. PKU 1655 Balancing Act(树+树的重心)

    #include<cstdio> #include<cstring> #include<algorithm> #define maxn 20005 using na ...

  5. 『左偏树 Leftist Tree』

    新增一道例题 左偏树 Leftist Tree 这是一个由堆(优先队列)推广而来的神奇数据结构,我们先来了解一下它. 简单的来说,左偏树可以实现一般堆的所有功能,如查询最值,删除堆顶元素,加入新元素等 ...

  6. POJ 1655 - Balancing Act 树型DP

    这题和POJ 3107 - Godfather异曲同工...http://blog.csdn.net/kk303/article/details/9387251 Program: #include&l ...

  7. poj1655 Balancing Act 找树的重心

    http://poj.org/problem? id=1655 Balancing Act Time Limit: 1000MS   Memory Limit: 65536K Total Submis ...

  8. POJ 1655 Balancing Act【树的重心】

    Balancing Act Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14251   Accepted: 6027 De ...

  9. POJ 1655.Balancing Act 树形dp 树的重心

    Balancing Act Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14550   Accepted: 6173 De ...

随机推荐

  1. git使用命令讲解

    1.创建版本库 ①选择一个合适的地方,创建一个空目录   mkdir learngit cd learngit ②通过git init命令把这个目录变成Git可以管理的仓库: git init Git ...

  2. Luogu 3384 【模板】树链剖分

    题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式 ...

  3. MyBatis返回map数据

    (1)接口中编写方法 //单行 public Map<String, Object> getEmpReturnMap(Integer id); //多行 @MapKey("id& ...

  4. 检查对象是否为NULL或者为Empty

    不管是在Winform开发,还是在asp.net 开发中当从一个数据源中获取数据时你总是不知道这个数据的状态,这个时候总要对她进行一次判断,不过每次进行一次判断总是要写怎么一堆代码,时间长了,总感觉不 ...

  5. CSS content换行实现字符点点点loading效果

    CSS代码如下: dot { display: inline-block; height: 1em; line-height: 1; text-align: left; vertical-align: ...

  6. 20175324王陈峤宇 2018-2019-2《Java程序设计》结对编程项目-四则运算 第一周 阶段性总结

    20175324王陈峤宇 2018-2019-2<Java程序设计>结对编程项目-四则运算 第一周 阶段性总结 需求分析 这次的结对作业是要求我们利用栈来设计一个计算器. 自动生成四则运算 ...

  7. Gradle 学习一

    参考教程:https://guides.gradle.org/consuming-jvm-libraries/ 安装Gradle 下载地址:https://guides.gradle.org 配置环境 ...

  8. linux端安装Anaconda,方便远端访问jupyter

    ipython notebook是一个基于浏览器的python数据分析工具,使用起来非常方便,具有极强的交互方式和富文本的展示效果.jupyter是它的升级版,它的安装也非常方便,一般Anaconda ...

  9. 记录k8s:k8s1.8.4无坑离线安装

    安装部署: 1. 使用vagrant 准备3太虚拟机,自己使用Vbox 准备3太也可以. 2. 按照 https://github.com/gjmzj/kubeasz 安装. 3. 使用letsenc ...

  10. Javascript高级编程学习笔记(93)—— Canvas(10) 模式及图像数据

    模式 模式其实就是重复的图像,用来填充或描边图形 要创建一个新模式,可以调用 createPattern()并传入两个参数 一个HTML img元素 用于表示如何重复的字符串 "repeat ...