pku 1655 Balancing Act 划分子树,DP

题意简要说明下,给出一颗树,如果删除一个节点,则会将这棵树变成一棵子树或者森林。定义节点的平衡数为删除这个节点后子树的最大节点数。求最小平衡数的节点以及最小平衡数。
还是老方法,树形DP,子树的节点数显然就为size[son[pos]],以及total-size[pos],取其最大值和当前答案比较即可。
贴代码
 1 # include <cstdio>
 2 # include <cstring>
 3 using namespace std;
 4 int g[20005],size[20005];
 5 int v[50000],nxt[50000],c;
 6 int num,total,ans=0xfffffff,minnum;
 7 inline void insert(int a,int b)
 8 {
 9     v[c]=b;
10     nxt[c]=g[a];
11     g[a]=c++;
12 }
13 void dfs(int pos,int fa)
14 {
15     
16         size[pos]=1;
17         for(int p=g[pos];p!=-1;p=nxt[p])
18         {
19             if(v[p]!=fa)
20             {
21                 dfs(v[p],pos);
22                 size[pos]+=size[v[p]];
23             }
24         }
25     
26 }
27 void cal(int pos,int fa)
28 {
29         int maxnum=-1;
30         for(int p=g[pos];p!=-1;p=nxt[p])
31             if(v[p]!=fa)
32             {
33                 cal(v[p],pos);
34                 if(size[v[p]]>maxnum)
35                     maxnum=size[v[p]];
36             }
37         if(pos!=1&&total-size[pos]>maxnum)
38             maxnum=total-size[pos];
39         if(maxnum<ans||maxnum==ans&&pos<minnum)
40             ans=maxnum,minnum=pos;
41     
42 }
43 int main()
44 {
45     int t;
46     scanf("%d",&t);
47     while(t--)
48     {
49         c=0;
50         memset(g,-1,sizeof(g));
51         scanf("%d",&num);
52         for(int i=1;i<num;i++)
53         {
54             int a,b;
55             scanf("%d%d",&a,&b);
56             insert(a,b);
57             insert(b,a);
58         }
59         dfs(1,-1);
60         ans=0xfffffff;
61         total=size[1];
62         cal(1,-1);
63         printf("%d %d\n",minnum,ans);
64     }
65     return 0;
66 
67 }


posted on 2010-10-25 21:57 yzhw 阅读(86) 评论(0)  编辑 收藏 引用 所属分类: DP


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2010年10月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

导航

统计

公告

统计系统

留言簿(1)

随笔分类(227)

文章分类(2)

OJ

最新随笔

搜索

积分与排名

最新评论

阅读排行榜