战略游戏题解
这道题一看就是一道树形dp的题目。
我们首先设f[i][1]表示第i个点选择,f[i][0]表示不选。
由此可以得出状态转移方程
当第i个点不放时,它的儿子必须放,所以f[i][0]+=f[to][1] to为i的子节点。
当第i个点放时,它的儿子可以也可以不放,我们取最小值f[i][1]+=min(f[to][0],f[to][1]) to为i的子节点。
#include<bits/stdc++.h> int n,x,y,k,tot,head[1501],f[1501][2]; struct jhh { int to,next; }a[3001]; int min(int x,int y) { if(x<y) return x; return y; } void add(int x,int y) { ++tot; a[tot].to=y; a[tot].next=head[x]; head[x]=tot; } void dfs(int x,int v) { f[x][1]=1; f[x][0]=0; if(head[x]==0) f[x][0]=9999999; for(int i=head[x];i;i=a[i].next) { int y=a[i].to; if(y!=v) { dfs(y,x); f[x][1]+=min(f[y][1],f[y][0]); f[x][0]+=f[y][1]; } } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&x,&k);x++; for(int j=1;j<=k;j++) { scanf("%d",&y);y++; add(x,y); add(y,x); } } dfs(1,0); printf("%d",min(f[1][1],f[1][0])); }