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.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#include #include #include using namespace std; vector 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 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])