Balancing Act

时限:1000ms

Description

Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any node from the tree yields a forest: a collection of one or more trees. Define the balance of a node to be the size of the largest tree in the forest T created by deleting that node from T. 
For example, consider the tree: 

Deleting node 4 yields two trees whose member nodes are {5} and {1,2,3,6,7}. The larger of these two trees has five nodes, thus the balance of node 4 is five. Deleting node 1 yields a forest of three trees of equal size: {2,6}, {3,7}, and {4,5}. Each of these trees has two nodes, so the balance of node 1 is two.

For each input tree, calculate the node that has the minimum balance. If multiple nodes have equal balance, output the one with the lowest number.

Input

The first line of input contains a single integer t (1 <= t <= 20), the number of test cases. The first line of each test case contains an integer N (1 <= N <= 20,000), the number of congruence. The next N-1 lines each contains two space-separated node numbers that are the endpoints of an edge in the tree. No edge will be listed twice, and all edges will be listed.

Output

For each test case, print a line containing two integers, the number of the node with minimum balance and the balance of that node.

Sample Input

1
7
2 6
1 2
1 4
4 5
3 7
3 1

Sample Output

1 2

树的重心也叫树的质心。找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡。利用树形dp的思想,对节点u的子树进行遍历。和树的直径不同的是,如果子树的分割确定了,那么子树之外的节点必定在一颗树上,不需要在dfs一次。
#include "stdio.h"
#include "algorithm"
#include "string.h"
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 20000 + 10;
bool vis[maxn];
struct edge {int to, next;
} e[maxn*2];
int n, num[maxn];
int size, cur;
int tot = 0;
int head[maxn];
void add_edge(int u, int v) {e[tot].to = v; e[tot].next = head[u];head[u] = tot++;
}
void dfs(int u) {num[u] = 0;int tr = 0;vis[u] = true;for (int i = head[u]; i != -1; i = e[i].next) {int v = e[i].to;if (vis[v]) continue;dfs(v);num[u] += num[v] + 1;tr = max(num[v] + 1, tr);} tr = max(n - num[u] - 1, tr); //剩下那棵树的大小if (tr < size || tr == size && cur > u) { //答案还要编号节点最小size = tr; cur = u;}
}
void init() {memset(vis, false, sizeof(vis));memset(head, -1, sizeof(head));tot = 0; size = INF;
}
int main(int argc, char const *argv[])
{int T;scanf("%d", &T);while (T--) {init();scanf("%d", &n);for (int i = 0; i < n-1; i++) {int u, v;scanf("%d%d", &u, &v); add_edge(u, v);add_edge(v, u);}dfs(1);printf("%d %d\n", cur, size);}return 0;
}

 

转载于:https://www.cnblogs.com/cniwoq/p/7247542.html

POJ 1655 Balancing Act[树的重心/树形dp]相关推荐

  1. POJ 1655 Balancing Act (树的重心)

    题目链接:http://poj.org/problem?id=1655 题意: 求树的重心(最小序号),以及去掉重心后子树节点最大是多少.(树的重心定义为:找到一个点,其所有的子树中最大的子树节点数最 ...

  2. POJ - 1655 Balancing Act(树的重心)

    题目链接:点击查看 题目大意:给一个树,删除其中一个点就会形成一个森林,点的平衡度为删除了这个节点后,所形成多个树,其中组成树的节点最多,节点个数就是那个平衡度. 题目分析:求树的重心,模板题: 树的 ...

  3. poj 1655 Balancing Act 树状dp

    //poj1655树状dp //求一个数的重心 // dfs找到节点v的各个子树的节点数 // 取最大值设为num[v],而v节点以上的子树的节点数 // 为总数-num[v]-1(包括v节点本身)设 ...

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

    传送门:POJ 1655 题目大意: 求树的重心,如果有多个重心则输出根节点编号最小的一个.树的重心也叫树的质心.找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后 ...

  5. POJ 1655 求树的重心(树形dp)

    题目链接 树的重心: 若树上的一个节点满足其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心. 1.任选一个点为根,只要统计出每个点的子树大小,就能很快求出每个点子树节点的数量的最大值. ...

  6. 『Balancing Act 树的重心』

    树的重心 我们先来认识一下树的重心. 树的重心也叫树的质心.找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡. 根据树的重心的定义,我们可 ...

  7. POJ-1655 Balancing Act 树的重心

    题意:完全符合树的重心:即找到一个点,其所有的子树中最大的子树节点最少. 代码如下: #include <cstdlib> #include <cstring> #includ ...

  8. M - Kill the tree 计蒜客 - 42552(2019icpc徐州/树的重心/树形dp)

    vj地址 题目大意:找到每一颗子树的重心 思路: 树的重心的性质: 树的重心如果不唯一,则至多有两个,且这两个重心相邻 通过连接一条端点分别在两个树的边,来将两个树合并成一个,那么新的重心肯定是在原来 ...

  9. POJ 1655 Balancing Act (求树的重心)【树形DP】(经典)

    <题目链接> 题目大意: 给你一棵树,任意去除某一个点后,树被分成了几个联通块,则该点的平衡值为所有分成的连通块中,点数最大的那个,问你:该树所有点中,平衡值最小的那个点是什么? 解题分析 ...

最新文章

  1. 【华为AI十强应用·上卷】官宣!这里的AI应用“神了”……
  2. harmonyos2.0开发者beta,华为鸿蒙 HarmonyOS 2.0 手机开发者 Beta 活动(广州站)报名开启...
  3. java的继承_java中的继承(一)
  4. UE4从4.15移植到4.16
  5. Server.Transfer 和Response.Redirect 比较
  6. Linux——less指令常用操作
  7. python opencv 膨胀_OpenCV-Python:形态学操作
  8. 店铺如何用视觉走出差异化?
  9. Java JDBC spring-jdbc
  10. 每周荐书:微服务、SQL调优、机器学习(评论送书)
  11. 15个网页数据采集中最常遇到的问题(干货)
  12. Android基础教程之Button事件发送消息到通知栏Notification
  13. java poi生成word 并插入 表格
  14. MAKEFILE【4】-Makefile中的wildcard用法
  15. linux磁盘分区6,Linux学习笔记(6)磁盘分区(LVM)
  16. 微信支付可以设置0元么?
  17. JAVA毕业设计课设源码分享50+例
  18. A40i使用笔记:系统配置
  19. Python学习笔记(7)——Matplotlib中的Axes.plot(绘制点、线和标记)的用法
  20. java 私有全局变量_java中的全局变量

热门文章

  1. GDCM:二个DICOM文件的diff差异的测试程序
  2. Boost:boost::mp11的使用实例
  3. ITK:使用基于多尺寸Hessian的量度来分割血管
  4. ITK:减去两个图像
  5. ITK:沿所选方向累积图像的像素
  6. VTK:可视化之FontFile
  7. VTK:PolyData之RibbonFilter
  8. VTK:Math之MatrixInverse
  9. OpenCV XML和YAML文件的文件输入和输出
  10. C++实现线性递归矩阵 linear recurrence matrix算法(附完整源码)