码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1054 Strategic Game (树形dp)

时间:2014-09-05 22:15:52      阅读:338      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   ar   for   div   

题目链接

题意:

给一颗树,用最少的点覆盖整棵树。

分析:

1:以当前节点为根节点,在该节点排士兵守护道路的最小消耗。在这种情况下,他的子节点可以安排士兵,也可以不安排士兵。可以从各个子节点两个不同状态(存在士兵,不存在士兵)的最值中选出最小的消耗,然后相加就求出了当前节点派士兵的最小消耗。

2:以当前节点为根节点,不存在士兵。这种情况十分清楚,因为当前节点没有士兵,那么这个节点到子节点之间的道路没有人守护,那么子节点就必须要安排士兵,因此这种情况下。这个节点的最小消耗就是每个子节点存在士兵的情况下的最小消耗的和。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cmath>
 6 #include <algorithm>
 7 #include <vector>
 8 #define LL __int64
 9 const int maxn = 1500+10;
10 using namespace std;
11 int d[maxn], a[maxn], vis[maxn];
12 vector<int>v[maxn];
13 
14 void dfs(int root)
15 {
16     int i;
17     vis[root] = 1;
18     int len = v[root].size();
19     for(i = 0; i < len; i++)
20     {
21         int tmp = v[root][i];
22         if(vis[tmp]) continue;
23         dfs(tmp);
24         d[root] += a[tmp];
25         a[root] += min(a[tmp], d[tmp]);
26     }
27     a[root] ++;
28 }
29 int main()
30 {
31     int n, i, x, m, b;
32     while(~scanf("%d", &n))
33     {
34         memset(a, 0, sizeof(a));
35         memset(d, 0, sizeof(d));
36         memset(vis, 0, sizeof(vis));
37 
38         for(i = 0; i < n; i++)
39         v[i].clear();
40         while(n--)
41         {
42             scanf("%d%*c%*c%d%*c", &x, &m);
43             while(m--)
44             {
45                 cin>>b;
46                 v[x].push_back(b);
47                 v[b].push_back(x);
48             }
49         }
50         dfs(0);
51         cout<<min(d[0], a[0])<<endl;
52     }
53     return 0;
54 }

 

HDU 1054 Strategic Game (树形dp)

标签:style   blog   http   color   os   io   ar   for   div   

原文地址:http://www.cnblogs.com/bfshm/p/3958730.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!