一颗树。每个节点都可以放士兵
士兵可以看到相邻的每一条边
要看到所有的边,问至少需要多少士兵?
上图只需要在1节点放置士兵即可。
定义状态 dp [ u] [ 0/1 ] 表示u这个节点不放/放士兵,以u为根的子树放置的最少士兵
根据题意,如果当前节点不放置士兵,那么它的子节点必须全部放置士兵,因为要满足士兵可以看到所有的边,所以
dp [ u ] [ 0 ] += dp [ u 的儿子 ] [ 1 ]
dp[u][1]+=min( dp [ u的儿子 ] [ 0 ] , dp [ u的儿子 ][1] )
#include <bits/stdc++.h> using namespace std; const int maxn=1509; vector<int>vec[maxn]; int n,k,num,indug[maxn]; int dp[maxn][2],chu[maxn]; void dfs(int now) { dp[now][1]=1; dp[now][0]=0; for(int i=0;i<vec[now].size();i++) { int w=vec[now][i]; dfs(w); dp[now][0]+=dp[w][1]; dp[now][1]+=min(dp[w][1],dp[w][0]); } } int main() { cin>>n; for(int i=1;i<=n;i++) { cin>>k>>num; for(int j=1;j<=num;j++) { int x; cin>>x; vec[k].push_back(x); indug[x]++; } } memset(dp,20,sizeof(dp)); int root;//找根 for(int i=0;i<=n-1;i++) if(indug[i]==0) root=i; dfs(root); cout<<min(dp[root][1],dp[root][0]); }