树的重心
时间:2022-07-28
本文章向大家介绍树的重心,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
定义:
1.找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心。 2.以这个点为根,那么所有的子树(不算整个树自身)的大小都不超过整个树大小的一半。
性质:
1.树中所有点到某一点距离之和中,到重心的距离和最短。
2.把两个树通过一条边相连得到一个新的树,那么新的树的重心在连接原来两个树的重心的路径上。 3.把一个树添加或删除一个叶子,那么它的重心最多只移动一条边的距离。
DP的记忆化搜索来求解。
const int maxn=500005;
int tot=0,n;
int ans,size;
int sx[maxn],head[maxn];
int vis[maxn];
struct edge
{
int to,next;
} eg[maxn];
void add(int u,int v)
{
eg[tot].to=v;
eg[tot].next=head[u];
head[u]=tot++;
}
void init()
{
tot=0;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
}
void dfs(int u)
{
vis[u]=1;
sx[u]=1;
int tmp=0;
for(int i=head[u]; i!=-1; i=eg[i].next)
{
int v=eg[i].to;
if(!vis[v])
{
dfs(v);
sx[u]+=sx[v];
tmp=max(tmp,sx[v]);
}
}
tmp=max(tmp,n-sx[u]);
if(size>tmp||size==tmp&&ans>u)
{
ans=u;
size=tmp;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
init();
int u,v;
scanf("%d",&n);
for(int i=1; i<n; i++)
{
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
size=INF;
dfs(1);
printf("%d %dn",ans,size);
}
}
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法