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

就是给你一棵树,让你在树上去掉一个节点,这样就形成了许多子树,设所有子树中点个数最多的那颗子树的点的个数为x,现在让这个x最小,问你应该剪掉哪个节点,x是多少?
根据树形结构的特殊性,从树根走到叶子节点是严格按照层次顺序的。我现在就开始做dp。首先我们先定义一个dp数组。
我们还需要一个num[x]数组,用来表示以x为树根的子树上有多少节点。
对于每一个节点,去掉它所得到的x的值是什么呢?1.它所有子节点为根的子树的最大值 2.除了x和它下面所有的子树,剩下全部的节点。这两者比较最大值就可以了。 刚刚看了白书,就是让找树的重心。
代码如下:
 #include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define M 20020
int n;
struct Node
{
int to,pre;
}edge[M*];
int head[M],tot,dp[M],num[M];
void init ()
{
memset(head,-,sizeof head);
tot=;
}
void addedge (int u,int v)
{
edge[tot].to=v;
edge[tot].pre=head[u];
head[u]=tot++;
}
void dfs (int u,int prenode)
{
dp[u]=;
num[u]=;
for (int i=head[u];i!=-;i=edge[i].pre)
{
int v=edge[i].to;
if (v==prenode)
continue;
dfs(v,u);
dp[u]=max(dp[u],num[v]);
num[u]+=num[v];
}
dp[u]=max(dp[u],n-num[u]);
}
int main()
{
int t;
scanf("%d",&t);
while (t--)
{
scanf("%d",&n);
init();
for (int i=;i<n;++i)
{
int u,v;
scanf("%d %d",&u,&v);
addedge(u,v);
addedge(v,u);
}
dfs(,-);
int ans1=,ans2=dp[];
for (int i=;i<=n;++i)
{
if (ans2>dp[i])
{
ans1=i;
ans2=dp[i];
}
}
printf("%d %d\n",ans1,ans2);
}
return ;
}

POJ 1655 Balancing Act (树状dp入门)的更多相关文章

  1. POJ 1655 - Balancing Act 树型DP

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

  2. POJ 1655 Balancing Act 树的重心

    Balancing Act   Description Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. ...

  3. POJ 1655 Balancing Act (树形DP求树的重心)

    题意: 求一棵树中以某个点为重心最小的子树集, 就是去掉这个点, 图中节点最多的联通块节点最少. 分析: 想知道这个点是不是最优的点, 只要比较它子树的数量和除去这部分其他的数量(它的父节点那部分树) ...

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

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

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

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

  6. [Codeforces743D][luogu CF743D]Chloe and pleasant prizes[树状DP入门][毒瘤数据]

    这个题的数据真的很毒瘤,身为一个交了8遍的蒟蒻的呐喊(嘤嘤嘤) 个人认为作为一个树状DP的入门题十分合适,同时建议做完这个题之后再去做一下这个题 选课 同时在这里挂一个选取节点型树形DP的状态转移方程 ...

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

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

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

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

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

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

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

    树的重心的定义是: 一个点的所有子树中节点数最大的子树节点数最小. 这句话可能说起来比较绕,但是其实想想他的字面意思也就是找到最平衡的那个点. POJ 1655 题目大意: 直接给你一棵树,让你求树的 ...

随机推荐

  1. Android中微信抢红包插件原理解析和开发实现

    一.前言 自从去年中微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导 ...

  2. 纯CSS 常见3D实例

    一.正方体 我认为正方体可以算是3D图像的基础吧,首先正方体是由六个相同的面所组成,其次就需要我们依次构造.(据体构造在代码中)成平图如下: 代码如下: <!DOCTYPE html> & ...

  3. 使用Echarts中遇到值得记录的小案例(一)

    需求部分 在开发项目的时候遇到一个需求,就是如何保证echarts图表里至少显示一个图例的数据(也就是最后一个图例不能变成unselected的状态)下图是最初加载时的画面 不想出现图例都被点击取消导 ...

  4. SpringBoot 快速构建微服务体系 知识点总结

    可以通过http://start.spring.io/构建一个SpringBoot的脚手架项目 一.微服务 1.SpringBoot是一个可使用Java构建微服务的微框架. 2.微服务就是要倡导大家尽 ...

  5. git开发实战:问题解决

    git作为一个高效的开发协作工具,其版本管理和分支管理是其高效管理代码的体现.但是我们在平时开发中,往往要一边修着bug一边做着新功能,这样有可能就会遇到以下几种场景 1.改完bug忘记切换分支了,代 ...

  6. TList TObjectList的区别和使用

    所在的单元 TList(Classes.pas) TObjectList(Contnrs.pas) TObjectList对象的创建方法有一个参数: constructor TObjectList.C ...

  7. python3反转列表的三种方式

    1.内建函数 reversed() li = [1,2,3,4,5,6] a = list(reversed(li)) print(a) 注意:reversed()函数返回的是一个迭代器,而不是一个L ...

  8. upc组队赛15 Made In Heaven【第K短路 A*】

    Made In Heaven 题目描述 One day in the jail, F·F invites Jolyne Kujo (JOJO in brief) to play tennis with ...

  9. 希尔排序(shell)理论---不含源码

    |   版权声明:本文为博主原创文章,未经博主允许不得转载. 希尔排序,是一个缩小增量排序.它根据步长来进行排序,步长不同可能会产生不同的序列,但是他们的最终结果是相同的,希尔排序的官方理论难以理解, ...

  10. JavaScript HashTable

    function HashTable() { var loseHashCode = function(key) { var hash = 0; for (var i = 0; i < key.l ...