Balancing Act
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10311 | Accepted: 4261 |
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.
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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。