AcWing 323. 战略游戏

原题链接

考察:树形dp

思路:

       因为要观察到所有的边,所以每条边上的点至少要放一个士兵,对于某子树的根u,f[u][1] = min(f[v][1],f[v][0]),f[u][0] = f[v][1].

       md,我是zz,看成要看到所有的点,导致这道题我没想出来= =

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 using namespace std;
 6 const int N = 1510;
 7 int f[N][2],n,idx,h[N];
 8 bool has_father[N];
 9 struct Road{
10     int fr,to,ne;
11 }road[N];
12 void add(int a,int b)
13 {
14     road[idx].fr = a,road[idx].to = b,road[idx].ne = h[a],h[a] = idx++;
15 }
16 void dfs(int u)
17 {
18     f[u][1] += 1;
19     for(int i=h[u];i!=-1;i=road[i].ne)
20     {
21         int v = road[i].to;
22         dfs(v);
23         f[u][1]+=min(f[v][1],f[v][0]);
24         f[u][0] += f[v][1];
25     }
26 }
27 int main()
28 {
29     while(scanf("%d",&n)!=EOF&&n)
30     {
31         int root = 0; idx = 0; memset(has_father,0,sizeof has_father);
32         memset(h,-1,sizeof h); memset(f,0,sizeof f);
33         for(int i=1;i<=n;i++)
34         {
35             int x,m;
36             scanf("%d:(%d)",&x,&m);
37             while(m--)
38             {
39                 int t; scanf("%d",&t);
40                 add(x,t);
41                 has_father[t] = 1;
42             }
43         }
44         while(has_father[root]) root++;
45         dfs(root);
46         printf("%d\n",min(f[root][1],f[root][0]));
47     }
48     return 0;
49 }

 

posted @ 2021-02-16 12:42  acmloser  阅读(74)  评论(0编辑  收藏  举报