| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 10311 | Accepted: 4261 |
Description

Input
Output
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;
}
原文地址:http://blog.csdn.net/u010885899/article/details/46493739