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 }