HDU 1054 Strategic Game
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 1054 Strategic Game相关的知识,希望对你有一定的参考价值。
树形DP。
dp[i][1]表示 在编号为 i 的节点上放置一个人,覆盖 编号为 i 的节点 的子树上所有边 需要的数量。
dp[i][0]表示 在编号为 i 的节点上不放置人,覆盖 编号为 i 的节点 的子树上所有边 需要的数量。
也可以用二分图匹配来做,在数量上,二分图的最小点覆盖数=二分图的最大匹配。
#include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<vector> #include<algorithm> using namespace std; const int maxn=1500+10; int n; int dp[maxn][3]; int tot[maxn]; vector<int>tree[maxn]; void init() { for(int i=0;i<=n;i++) tree[i].clear(); memset(dp,0,sizeof dp); memset(tot,0,sizeof tot); } void read() { for(int i=1;i<=n;i++) { int a,b,c; scanf("%d:(%d)",&a,&b); while(b--) { scanf("%d",&c); tree[a].push_back(c); tot[c]++; } } } void dfs(int now) { if(!tree[now].size()) { dp[now][0]=0; dp[now][1]=1; return; } for(int i=0;i<tree[now].size();i++) dfs(tree[now][i]); for(int i=0;i<tree[now].size();i++) dp[now][0]+=dp[tree[now][i]][1]; for(int i=0;i<tree[now].size();i++) dp[now][1]+=min(dp[tree[now][i]][1],dp[tree[now][i]][0]); dp[now][1]++; } void work() { int ans=0; for(int i=0;i<n;i++) if(!tot[i]) { dfs(i); ans=ans+min(dp[i][1],dp[i][0]); } printf("%d\n",ans); } int main() { while(~scanf("%d",&n)) { init(); read(); work(); } return 0; }
以上是关于HDU 1054 Strategic Game的主要内容,如果未能解决你的问题,请参考以下文章