树的重心 poj - 1655 和 poj - 3107
2017-10-10 21:47
281 查看
首先知道 树的重心定义为: 找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡. 实际上树的重心在树的点分治中有重要的作用, 可以避免N^2的极端复杂度(从退化链的一端出发),保证nlogn的复杂度, 利用树型dp可以很好地求树的重心.
poj - 1655
//题意: 就是求树的重心编号, 以及删除该点后节点数size, 如果size相同, 那么就选编号较小的那个.
//就是一道模板题, 直接dfs一遍树. 然后不断更新答案即可. 详情请看代码
AC Code
poj - 3107
//题意: 就是按升序输出所有的树的重心编号, 因为可能存在一些点, 使得删去他们后最大子树的节点数可能相等, 那么加一个判断即可.
AC Code
poj - 1655
//题意: 就是求树的重心编号, 以及删除该点后节点数size, 如果size相同, 那么就选编号较小的那个.
//就是一道模板题, 直接dfs一遍树. 然后不断更新答案即可. 详情请看代码
AC Code
const int maxn = 2e4+5; int cas=1,n; int a[maxn]; int son[maxn]; int cnt,head[maxn]; struct node { int to,next; }e[maxn*2]; void add(int u,int v) { e[cnt] = (node){v,head[u]}; head[u] = cnt++; } int ans ,siz; void dfs(int u,int fa) { son[u] = 0; int tmp = 0; for(int i=head[u]; ~i ; i = e[i].next){ int to = e[i].to; if(fa == to) continue; dfs(to,u); son[u] += son[to] + 1; tmp = max(tmp,son[to]+1); } tmp = max(tmp,n - son[u] - 1); if(tmp < siz || (tmp == siz && u > ans)) { ans = u; siz = tmp; } } void solve() { while(~scanf("%d",&n)){ cnt = 0; Fill(head,-1); Fill(son,0); ans = -1; siz = inf; for(int i=1;i<n;i++){ int u,v; scanf("%d%d",&u,&v); add(u,v); add(v,u); } dfs(1,-1); printf("%d %d\n",ans,siz); } }
poj - 3107
//题意: 就是按升序输出所有的树的重心编号, 因为可能存在一些点, 使得删去他们后最大子树的节点数可能相等, 那么加一个判断即可.
AC Code
const int maxn = 5e4+5; int cas=1,n; int a[maxn]; int son[maxn],ans[maxn]; int cnt,head[maxn]; struct node { int to,next; }e[maxn*2]; void add(int u,int v) { e[cnt] = (node){v,head[u]}; head[u] = cnt++; } int num ,siz; void dfs(int u,int fa) { son[u] = 0; int tmp = 0; for(int i=head[u]; ~i ; i = e[i].next){ int to = e[i].to; if(fa == to) continue; dfs(to,u); son[u] += son[to] + 1; tmp = max(tmp,son[to]+1); } tmp = max(tmp,n - son[u] - 1); if(tmp < siz){ siz = tmp; num = 0; ans[++num] = u; } else if(tmp == siz){ ans[++num] = u; } } void solve() { while(~scanf("%d",&n)){ cnt = 0; Fill(head,-1); Fill(son,0); siz = inf; for(int i=1;i<n;i++){ int u,v; scanf("%d%d",&u,&v); add(u,v); add(v,u); } dfs(1,-1); sort(ans+1,ans+num+1); for(int i=1;i<=num;i++){ printf("%d%c",ans[i],i==num?'\n':' '); } } }
相关文章推荐
- POJ 1655 Balancing Act&&POJ 3107 Godfather(树的重心)
- poj 1655(3107、2378) 求树的重心
- 求树的重心 POJ 1655、POJ 3107 树形DP
- POJ 1655 +POJ 3107【求树的重心】
- poj 1655 and 3107 and 2378 树形dp(树的重心问题)
- 【poj 1655,3107】树的重心(树形dp)
- POJ1655-树的重心&树形dp-Balancing Act
- POJ 3107 求树的重心
- poj 1655 树的重心
- poj1655(树的重心)
- 【树的重心】 POJ 1655 Balancing Act
- POJ 1655 Balancing Act (树的重心)
- POJ 1655 树的重心 解题报告
- POJ 1655 Balancing Act (树的重心)
- poj 1655 Balancing Act【树的重心】
- POJ 1655 Balancing Act【树的重心】
- poj 1655 求树的重心(质心)
- POJ 3107 dfs 树的重心
- poj 1655 Balancing Act(求树的重心)
- poj-1655-树的重心