树的重心及其一些性质。poj3107 && poj 1655
来源:互联网 发布:绑架恐怖分子家属 知乎 编辑:程序博客网 时间:2024/04/30 07:26
定义
树的重心:删去重心后,生成的多棵树尽可能平衡。即以这个点为根,那么所有的子树(不算整个树自身)的大小都不超过整个树大小的一半。(所有子树的最大块的节点最小)
性质
性质 1 :树中所有点到某个点的距离和中,到重心的距离和是最小的,如果有两个距离和,他们的距离和一样。
性质 2 :把两棵树通过某一点相连得到一颗新的树,新的树的重心必然在连接原来两棵树重心的路径上。
性质 3 :一棵树添加或者删除一个节点,树的重心最多只移动一条边的位置。
性质 2 :把两棵树通过某一点相连得到一颗新的树,新的树的重心必然在连接原来两棵树重心的路径上。
性质 3 :一棵树添加或者删除一个节点,树的重心最多只移动一条边的位置。
求法
DFS
点u ,找到所有u的儿子树中 最大节点数,和u的父亲树 n-son[u]-1; 取两者最大值! 就可以找到删除节点u,可以得到的子树最大块。
维护删除所有节点的最小值即可.
给出两个模板题
POJ 3107 http://poj.org/problem?id=3107
#include <iostream>#include<stdio.h>#include<algorithm>#include<string.h>#include<queue>using namespace std;const int maxn=100100;int head[maxn];struct node{ int to,next;}edge[maxn];int cnt=0;int maxson[maxn];int son[maxn];int ans;int n;bool vis[maxn];void add(int u,int v){ edge[cnt].to=v; edge[cnt].next=head[u] ;head[u]=cnt++;}void init(){ cnt=0; ans=maxn*100; memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis));}void dfs(int u){ vis[u]=1; son[u]=0; maxson[u]=0; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(!vis[v]) { dfs(v); son[u]+=(son[v]+1); maxson[u]=max(maxson[u],son[v]+1); } } maxson[u]=max(maxson[u],n-son[u]-1); if(ans>maxson[u]) ans=maxson[u];}int main(){ while(scanf("%d",&n)!=EOF) { init(); for(int i=1;i<n;++i) { int v,u; scanf("%d%d",&u,&v); add(u,v); add(v,u); } dfs(1); int flag=1; for(int i=1;i<=n;++i) { if(maxson[i]!=ans) continue; if(flag) { flag=0; printf("%d",i); } else printf(" %d",i); } printf("\n"); } return 0;}
POJ 1655 http://poj.org/problem?id=1655
#include <iostream>#include<algorithm>#include<stdio.h>#include<string.h>using namespace std;const int maxn= 40020;bool vis[maxn];int head[maxn];int son[maxn];struct node{ int to,next;}edge[maxn*2];int cnt=0;int ans,pos;int n;void add(int u,int v){ edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt++;}void init(){ memset(vis,0,sizeof(vis)); memset(head,-1,sizeof(head)); cnt=0; ans=maxn*maxn;}void dfs(int u){ vis[u]=1; son[u]=0; int t=0; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(!vis[v]) { dfs(v); son[u]=son[u]+son[v]+1; t=max(t,son[v]+1); } } t=max(t,n-1-son[u]); if(t<ans||(t==ans&&pos>u)) { ans=t; pos=u; }}int main(){ int T; scanf("%d",&T); while(T--) { scanf("%d",&n); init(); for(int i=1;i<n;++i) { int a,b; scanf("%d%d",&a,&b); add(a,b); add(b,a); } dfs(1); printf("%d %d\n",pos,ans); } return 0;}
阅读全文
0 0
- 树的重心及其一些性质。poj3107 && poj 1655
- 树的重心及其一些性质
- poj3107 树的重心
- poj3107(树的重心)
- 树的重心求法POJ3107
- poj3107 树的重心 非stl实现
- 【poj1655】【poj3107】【求树的重心】
- POJ3107 Godfather 求树的重心
- POJ3107-树的重心&树形DP-Godfather
- poj3107 Godfather(树的重心)
- 树的“重心”的一些性质及动态维护
- POJ 1655 树的重心
- poj 1655 树的重心
- poj 1655 树的重心
- poj-1655 树的重心
- 树的重心 poj-1655
- 【CodeForces 686 D. 】 【树的重心性质】
- 树的重心 poj
- 基于Laravel开发的CMS
- C++并发参考资料
- A+B for Input-Output Practice (V)
- 快速排序算法
- 使用powerdesigner连接MySQL并设置逆向工程图文教程
- 树的重心及其一些性质。poj3107 && poj 1655
- spring mvc demo
- spring boot 中配置文件的读取和多环境配置
- 事件冒泡和事件捕获
- [Unity知识点整理]关于旋转
- 1134: 生日日数
- 电商项目总结
- LIST 和SET hashmap hashtable
- 单链表的小应用