您的位置:首页 > 其它

(POJ 1655 Balancing Act)树型DP + 删点

2017-03-15 22:19 260 查看
Balancing Act

Time Limit: 1000MS Memory Limit: 65536K

Total Submissions: 13137 Accepted: 5548

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

Source

POJ Monthly–2004.05.15 IOI 2003 sample task

/*
2017/3/11
time: 485MS

题意:有一棵有n个节点的树,问你删除哪些节点后,使剩下的子树中节点数最大的值最小?

分析:(这是之前POJ 1741 tree这一题的一个子问题)
题目不难,先我们求出去掉每个节点后的最大值,然后找出其中的最小值,最后遍历一遍就可
在找出删除每个节点后的最大值,我们用dfs_node()首先求出以每个节点为根的子树的节点数目nodes[i]
然后删除i节点后的最大值就等于:以他每个孩子节点为根的子树的节点数目的最大值,和n - nodes[i] 中的大者
关于上面的问题我们直接dfs一遍更新即可

*/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
using namespace std;

const int maxn = 50010;
struct edge
{
int v,next;
}edges[2*maxn];

int head[maxn],e,n;
int nodes[maxn],maxnum[maxn];

void addedges(int u,int v)
{
edges[e].v = v;
edges[e].next = head[u];
head[u] = e++;
}

void dfs_subnode(int u,int f)
{
nodes[u] = 1;
for(int i=head[u];i!=-1;i=edges[i].next)
{
int v = edges[i].v;
if(v == f) continue;
dfs_subnode(v,u);
nodes[u] += nodes[v];
}
}

void dfs_up(int u,int f)
{
maxnum[u] = n - nodes[u];
for(int i=head[u];i!=-1;i=edges[i].next)
{
int v = edges[i].v;
if(v == f) continue;
if(maxnum[u] < nodes[v]) maxnum[u] = nodes[v];
dfs_up(v,u);
}
}

int main()
{
int u,v;
while(scanf("%d",&n)!=EOF)
{
memset(head,-1,sizeof(head));
e = 0;
for(int i=0;i<n-1;i++)
{
scanf("%d%d",&u,&v);
addedges(u,v);
addedges(v,u);
}
dfs_subnode(1,0);
dfs_up(1,0);
int minans = maxn;
for(int i=1;i<=n;i++) if(minans > maxnum[i])
minans = maxnum[i];
int t = 0;
for(int i=1;i<=n;i++) if(maxnum[i] == minans)
{
t++;
if(t == 1) printf("%d",i);
else printf(" %d",i);
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: