pku 1694 An Old Stone Game 树上的贪心

题意是这样,有一个篮子里放有若干个石子,每次可以在树的一个叶节点上放一个石子,如果一个节点的所有儿子都被放上石子,则将其儿子上的所有石子放回到篮子中,在该节点上放上一个石子。问要使得根节点上有一个石子,篮子中开始至少有多少个石子。
这题是基于树的一个贪心,假设当前节点为i,其儿子节点k放入1石子至少需要篮子中初始石子的数量为num[k],则在当前节点放入一个石子的策略是先将num[k]最大的子节点先放置,然后求得k-1+num[k]的最大值即为当前节点的num值(k为第k个儿子节点)
代码如下
 1 # include <cstdio>
 2 # include <vector>
 3 # include <iostream>
 4 # include <algorithm>
 5 using namespace std;
 6 const int N=201;
 7 int n;
 8 vector<int> g[N];
 9 int minnum[N];
10 bool cmp(const int &a,const int &b)
11 {
12     return minnum[a]>minnum[b];
13 }
14 void dfs(int pos)
15 {
16     if(g[pos].empty())
17        minnum[pos]=1;
18     else
19     {
20         for(int i=0;i<g[pos].size();i++)
21           dfs(g[pos][i]);
22         sort(g[pos].begin(),g[pos].end(),cmp);
23         int max=-1;
24         for(int i=0;i<g[pos].size();i++)
25           if(i+minnum[g[pos][i]]>max)
26              max=i+minnum[g[pos][i]];
27         minnum[pos]=max;
28     }
29 }
30 int main()
31 {
32     int testcase;
33     scanf("%d",&testcase);
34     while(testcase--)
35     {
36        scanf("%d",&n);
37        for(int i=1;i<=n;i++)
38        {
39           int num,pos;
40           scanf("%d %d",&pos,&num);
41           g[pos].clear();
42           while(num--)
43           {
44              int t;
45              scanf("%d",&t);
46              g[pos].push_back(t);
47           }
48        } 
49        dfs(1);
50        printf("%d\n",minnum[1]);
51     }
52     //system("pause");
53     return 0;
54 }
55 


posted on 2010-10-18 02:11 yzhw 阅读(232) 评论(0)  编辑 收藏 引用 所属分类: graph


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


<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

公告

统计系统

留言簿(1)

随笔分类(227)

文章分类(2)

OJ

最新随笔

搜索

积分与排名

最新评论

阅读排行榜