很纠结的一道题啊,看起来很简单,一写起来就各种搞不定!!!

开始没怎么想就写代码了,我的思路:建立有向图,正着搜一遍,反正搜一遍,两次dfs,最后把两个结果相融合起来,但是最后不好处理,导致各种搞不定,真杯具!!

上网搜了一个代码,超简单,看了一下就明白了,以后做题一定要先把思路理清晰,不能急着敲代码!

题意:

思路:找平衡点,用dfs遍历没个节点,求出该节点的子树中有多少个节点,若有多个孩子则记录最大的子树的节点的个数保存到一个数组中,

即该数组是保存着以该节点为根的树的平衡数,然后找这个数组的中最小的平衡数,并记录该节点。

不再多做解释,代码一看就懂了!

代码:

View Code
 1 # include<stdio.h>
2 # include<string.h>
3 # define N 20005
4 struct node{
5 int from,to,next;
6 }edge[2*N];
7 int head[N],tol,visit[N],n,val[N];
8 void add(int a,int b)
9 {
10 edge[tol].from=a;edge[tol].to=b;edge[tol].next=head[a];head[a]=tol++;
11 }
12 int max(int a,int b)
13 {
14 return a>b?a:b;
15 }
16 int dfs(int root,int father)
17 {
18 int u,sum,j,Max,temp;
19 sum=1;
20 Max=-1;
21 for(j=head[root];j!=-1;j=edge[j].next)
22 {
23 u=edge[j].to;
24 if(u!=father)
25 {
26 temp=dfs(u,root);
27 sum+=temp;
28 Max=max(Max,temp);
29 }
30 }
31 val[root]=max(Max,n-sum);
32 return sum;
33 }
34 int main()
35 {
36 int i,min,index,ncase,a,b;
37 scanf("%d",&ncase);
38 while(ncase--)
39 {
40 scanf("%d",&n);
41 memset(head,-1,sizeof(head));
42 tol=0;
43 for(i=1;i<n;i++)
44 {
45 scanf("%d%d",&a,&b);
46 add(a,b);
47 add(b,a);
48 }
49 dfs(1,0);
50 min=N;
51 for(i=1;i<=n;i++)
52 {
53 if(val[i]<min) {min=val[i];index=i;}
54 }
55 printf("%d %d\n",index,min);
56 }
57 return 0;
58 }

posted on 2011-07-23 10:18  奋斗青春  阅读(683)  评论(0编辑  收藏  举报