POJ 1655:Balancing Act
2015-06-14 19:58
274 查看
Balancing Act
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
Sample Output
表示头一次接触树形dp,一开始的思路想到了要用dfs,并且使用max_i数组表示当前状况下该节点其孩子节点中最大的值,然后sum数组表示当前状况下该节点所带的节点数量,但是这样的话,就得从每一个节点都要深度搜索一遍,才能得到正确结果,结果提交果然TLE。后来发现深度搜索节点度数为1的就够了,结果还是TLE。最后,看到别人的代码,跟我一样的思路,也是sum数组,还有一个son数组,但是用sum[1]-sum[i]表示了除了当前节点的孩子节点,其父亲节点那一个分支段内的节点数量。对这个思路啧啧称奇,责怪自己有没有想到,后面的事情就很简单,之前已经比较过自己的孩子哪一个节点数最多了,这次直接两两比较即可。
代码:
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10311 | Accepted: 4261 |
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,一开始的思路想到了要用dfs,并且使用max_i数组表示当前状况下该节点其孩子节点中最大的值,然后sum数组表示当前状况下该节点所带的节点数量,但是这样的话,就得从每一个节点都要深度搜索一遍,才能得到正确结果,结果提交果然TLE。后来发现深度搜索节点度数为1的就够了,结果还是TLE。最后,看到别人的代码,跟我一样的思路,也是sum数组,还有一个son数组,但是用sum[1]-sum[i]表示了除了当前节点的孩子节点,其父亲节点那一个分支段内的节点数量。对这个思路啧啧称奇,责怪自己有没有想到,后面的事情就很简单,之前已经比较过自己的孩子哪一个节点数最多了,这次直接两两比较即可。
代码:
#include <iostream> #include <vector> #include <string> #include <cstring> using namespace std; vector <int> node[20005]; int result,result_num; int used[20005]; int sum[20005]; int max_i[20005]; int dfs(int i) { used[i]=1; int k; sum[i]=0; max_i[i]=0; for(k=0;k<node[i].size();k++) { if(!used[node[i][k]]) { int temp = dfs(node[i][k]); sum[i]=sum[i]+temp; if(temp>max_i[i]) { max_i[i]=temp; } } } used[i]=0; return sum[i]+1; } int main() { int count,N; cin>>count; while(count--) { cin>>N; int i,flag; result=20005; memset(node,0,sizeof(node)); memset(used,0,sizeof(used)); for(i=1;i<=N-1;i++) { int node1,node2; cin>>node1>>node2; node[node1].push_back(node2); node[node2].push_back(node1); } dfs(1); for(i=1;i<=N;i++) { if(max(max_i[i],sum[1]-sum[i])<result) { result=max(max_i[i],sum[1]-sum[i]); result_num=i; } } cout<<result_num<<" "<<result<<endl; } return 0; }
相关文章推荐
- js中的闭包之我理解
- POJ 1655:Balancing Act
- FaceBook/infer-infer捕捉的bug类型
- Phthon学习笔记(四):生成列表
- JAVA实验五(网络编程)
- Reverse Integer
- 解决java压缩图片透明背景变黑色的问题
- 解决java压缩图片透明背景变黑色的问题
- LeetCode ContainsDuplicate
- c++ list, vector,deque, map,set 区别与用法比较
- java对象的强引用,软引用,弱引用和虚引用
- 四季
- HDFS的优缺点
- eclipse常用插件
- C++ 多态的原理
- 面对我的恐惧
- Linux内核中的鸡与蛋
- Hadoop中HDFS写入文件的原理剖析
- 匈牙利算法模板
- stl 迭代器失效