http://poj.org/problem?id=1655
树状DP,双向建图,以1为树的根节点遍历一遍
1 #include <stdio.h> 2 #include <string.h> 3 #include <vector> 4 5 #define N 20010 6 7 using namespace std; 8 9 vector<int> a[N]; 10 11 int n, mark[N], result, resulti; 12 13 int dfs(int x) 14 { 15 int i, j, temp, sum = 1, max_son = 0; 16 //printf("%d: ( ", x); 17 for(i=0; i<a[x].size(); i++) 18 { 19 j = a[x][i]; 20 if(!mark[j]) 21 { 22 mark[j] = 1; 23 temp = dfs(j); 24 sum += temp; 25 max_son = max(max_son, temp); 26 } 27 } 28 max_son = max(n-sum, max_son); 29 if(max_son < result) 30 { 31 result = max_son; 32 resulti = x; 33 } 34 //printf(" *%d %d) ", sum, max_son); 35 return sum; 36 } 37 38 int main() 39 { 40 int t, i, x, y; 41 scanf("%d", &t); 42 while(t-- && scanf("%d", &n)) 43 { 44 for(i=1; i<=n; i++) 45 { 46 a[i].clear(); 47 } 48 for(i=2; i<=n; i++) 49 { 50 scanf("%d%d", &x, &y); 51 a[x].push_back(y); 52 a[y].push_back(x); 53 } 54 memset(mark, 0, sizeof(mark)); 55 result = 1<<30; 56 resulti = -1; 57 mark[1] = 1; 58 dfs(1); 59 printf("%d %d\n", resulti, result); 60 } 61 return 0; 62 }