HDU 1054 Strategic Game(最小点覆盖+树形dp)

题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=106048#problem/B

题意:给出一些点相连,找出最小的点数覆盖所有的

用树形dp来解决

dp[i][0]表示i点不选,dp[i][1]表示i点选,dp[i][0] = sum{ dp[ son[i] ][1] }, // i不选,则i的子节点全选, dp[i][1] = sum { min( dp[ son[i] ][0], dp[ son[i] ][1] ) } + 1, i选的时候,子节点可选可不选,

在处理这题建立双向树,设dp[i][1] = 1;dp[i][0] = 0;

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <vector>
 6 using namespace std;
 7 const int Max = 1500 + 10;
 8 vector<int> son[Max];
 9 int dp[Max][2],n,vis[Max];
10 void Input()
11 {
12     int root,cnt,s;
13     for(int i = 0; i < n; i++)
14         son[i].clear();
15     for(int i = 0; i < n; i++)
16     {
17         scanf("%d:(%d)", &root, &cnt);
18         while(cnt--)
19         {
20             scanf("%d", &s);
21             son[root].push_back(s);
22             son[s].push_back(root);
23         }
24     }
25 }
26 void dfs(int root)
27 {
28     vis[root] = 1;
29     int len = (int) son[root].size();
30     dp[root][1] = 1;
31     dp[root][0] = 0;
32     for(int i = 0; i < len; i++)
33     {
34         if(vis[ son[root][i] ])
35             continue;
36         dfs(son[root][i]);
37         dp[root][1] += min(dp[ son[root][i] ][1], dp[ son[root][i] ][0]);
38         dp[root][0] += dp[ son[root][i] ][1];
39     }
40 }
41 void solve()
42 {
43     memset(dp, 0, sizeof(dp));
44     memset(vis, 0, sizeof(vis));
45     dfs(0);
46 }
47 int main()
48 {
49     while(scanf("%d", &n) != EOF)
50     {
51         Input();
52         solve();
53         if(n == 0)
54             printf("0\n");
55         else
56         {
57             printf("%d\n", min(dp[0][0], dp[0][1]));
58         }
59 
60     }
61     return 0;
62 }
View Code

 

posted @ 2016-02-06 14:48  zhaop  阅读(161)  评论(0编辑  收藏  举报