题意:

给你一个由n个节点n-1条边构成的一棵树,你需要输出树的重心是那个节点,以及重心删除后得到的最大子树的节点个数size,如果size相同就选取编号最小的

题解:

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

洛谷中P5666树的重心  对树的重心还有这样一种描述:

一个大小为 n 的树由 nn 个结点与 n−1 条无向边构成,且满足任意两个结点间有且仅有一条简单路径。在树中删去一个结点及与它关联的边,树将分裂为若干个子树;而在树中删去一条边(保留关联结点,下同),树将分裂为恰好两个子树。

对于一个大小为 n 的树与任意一个树中结点 c,称 c 是该树的重心当且仅当在树中删去 c 及与它关联的边后,分裂出的所有子树的大小均不超过 floor(n/2)(其中 floor⌊x⌋ 是向下取整函数)。对于包含至少一个结点的树,它的重心只可能有 1 或 2 个。

树的重心的性质:
1.树中所有点到某个点的距离和中,到重心的距离和是最小的;如果有两个重心,那么他们的距离和一样。
2.把两个树通过一条边相连得到一个新的树,那么新的树的重心在连接原来两个树的重心的路径上。
3.把一个树添加或删除一个叶子,那么它的重心最多只移动一条边的距离。

回归原题:

这道题我们可以随便找一个节点当作树根,然后dfs处理出来每一个节点的子节点的数量sonnum和每一个节点的子树中最大那颗子树的大小sonmax

树的定义中说过:“找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心

那么对于一个节点x,它所有子树中最大子树节点数就是:max(sonmax[i],n-sonnum[i])

sonmax[i]:表示的是x节点的子树中最大那颗子树的大小

n-sonnum[i]:表示的是不是x的子节点的剩下所有点构成的那颗树的大小

代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define mem(a) memset(a,0,sizeof(a))
#define mem_(a) memset(a,-1,sizeof(a))
const int maxn=2e4+10;
const int INF=0x3f3f3f3f;
//链式前向星
struct node
{
int to,w,next;
}e[maxn*2]; //这个是有多少边数组就开多少
int head[maxn],cnt,sonnum[maxn],sonmax[maxn];
void add_edge(int x,int y,int z)
{
e[cnt].to=y;
e[cnt].w=z;
e[cnt].next=head[x];
head[x]=cnt++;
}
void dfs(int now,int pre)
{
sonnum[now]=1;
sonmax[now]=0;
for(int i=head[now];~i;i=e[i].next)
{
int to=e[i].to;
if(to==pre) continue;
dfs(to,now);
sonnum[now]+=sonnum[to];
sonmax[now]=max(sonmax[now],sonnum[to]);
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
cnt=1;
mem_(head);
for(int i=1;i<n;++i)
{
int x,y;
scanf("%d%d",&x,&y);
add_edge(x,y,0);
add_edge(y,x,0);
}
dfs(1,0);
int minn=INF,pos;
for(int i=1;i<=n;++i)
{
//根据树的重心的定义,我们发现判断一个点是不是重心 只要把这个点去掉
//看它剩下的子树结点的个数的最大值是不是最小就ok了
//子树有两种:一个是往下的即sonMax[i],另一个是往上的 即n - sonNum[i]
//printf("%d %d***********\n",sonmax[i],n-sonnum[i]);
if(minn>max(sonmax[i],n-sonnum[i]))
{ minn=max(sonmax[i],n-sonnum[i]);
pos=i;
}
}
printf("%d %d\n",pos,minn);
}
return 0;
}

POJ 1655 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. POJ 1655 - Balancing Act 树型DP

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

  3. # [Poj 3107] Godfather 链式前向星+树的重心

    [Poj 3107] Godfather 链式前向星+树的重心 题意 http://poj.org/problem?id=3107 给定一棵树,找到所有重心,升序输出,n<=50000. 链式前 ...

  4. 链式前向星版DIjistra POJ 2387

    链式前向星 在做图论题的时候,偶然碰到了一个数据量很大的题目,用vector的邻接表直接超时,上网查了一下发现这道题数据很大,vector可定会超的,不会指针链表的我找到了链式前向星这个好东西,接下来 ...

  5. POJ.1655 Balancing Act POJ.3107 Godfather(树的重心)

    关于树的重心:百度百科 有关博客:http://blog.csdn.net/acdreamers/article/details/16905653 1.Balancing Act To POJ.165 ...

  6. poj 1655 Balancing Act 求树的重心【树形dp】

    poj 1655 Balancing Act 题意:求树的重心且编号数最小 一棵树的重心是指一个结点u,去掉它后剩下的子树结点数最少. (图片来源: PatrickZhou 感谢博主) 看上面的图就好 ...

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

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

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

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

  9. poj 1655 Balancing Act(找树的重心)

    Balancing Act POJ - 1655 题意:给定一棵树,求树的重心的编号以及重心删除后得到的最大子树的节点个数size,如果size相同就选取编号最小的. /* 找树的重心可以用树形dp或 ...

随机推荐

  1. 深入理解static、volatile关键字

    static 意思是静态的,全局的.被修饰的东西在一定范围内是共享的,被类的所有实例共享,这时候需要注意并发读写的问题. 只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内找到他们. ...

  2. Head First 设计模式 —— 12. 状态 (State) 模式

    思考题 public class GumballMachine { final static int SOLD_OUT = 0; final static int NO_QUARTER = 1; fi ...

  3. 使用 C# 9 的records作为强类型ID - 初次使用

    强类型ID 实体通常是整数,GUID或者string类型,因为数据库直接支持这些类型,但是,如果实体的ID的类型是一样的,比如都是整数的ID,这有可能会出现ID值传错的问题,看下边的示例. publi ...

  4. kubernets之pod的标签拓展

    一 标签的拓展使用 1.1 标签的作用范围不仅仅适用于pod对node以及其他类的大部分资源同样适用 k label node node01 gpu=true k是kubectl的别名形式 同样对于n ...

  5. P1220 关路灯(区间规划)

    题目描述 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯. 为了给村 ...

  6. PHP反序列化 - Pikachu

    概述 序列化serialize()序列化说通俗点就是把一个对象变成可以传输的字符串,比如下面是一个对象: class S{ public $test="pikachu"; } $s ...

  7. 利用vbs隐藏dos窗口

    方法一: option explicitdim wshshellset wshshell=wscript.createobject("wscript.shell")wshshell ...

  8. 探索微软开源Python自动化神器Playwright

    相信玩过爬虫的朋友都知道selenium,一个自动化测试的神器工具.写个Python自动化脚本解放双手基本上是常规的操作了,爬虫爬不了的,就用自动化测试凑一凑. 虽然selenium有完备的文档,但也 ...

  9. 特征预处理之归一化&标准化

    写在前面 这篇博客的主要内容 应用MinMaxScaler实现对特征数据进行归一化 应用StandardScaler实现对特征数据进行标准化 特征预处理 定义 ​ 通过一些转换函数将特征数据转换成更加 ...

  10. 【Android】报错 Please ensure Hyper-V is disabled in Windows Features, or refer to the Intel HAXM 的解决方案

    参考文章 实测华为锐龙本(adm yes)安装Android avd虚拟机教程 环境 Android Studio 3.6; Windows 1909; AMD Ryzen 4800U with Ra ...