简单的树形dp
要求的是最少的派兵个数
dp[i][0]=sum(dp[j][1])
dp[i][1]=sum(min(dp[j][1],dp[j][0]))
要建成有向树
然后dfs
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<string.h>
using namespace std;
#define maxn 1505
int n,vis[maxn];
int dp[maxn][maxn];
struct node
{
int fa;
vector<int> ch;
}s[maxn];
void dfs(int n)
{
vis[n]=1;
for(int i=0;i<s[n].ch.size();++i)
{
if(!vis[s[n].ch[i]])
{
dfs(s[n].ch[i]);
}
dp[n][0]+=dp[s[n].ch[i]][1];
dp[n][1]+=min(dp[s[n].ch[i]][1],dp[s[n].ch[i]][0]);
}
dp[n][1]+=1;
}
int main()
{
while(~scanf("%d",&n))
{
memset(dp,0,sizeof dp);
memset(s,0,sizeof s);
int k,num;
for(int i=0;i<n;++i)
{
scanf("%d:(%d)",&num,&k);
int ea;
for(int j=0;j<k;++j)
{
scanf("%d",&ea);
s[num].ch.push_back(ea);
// s[ea].ch.push_back(num);
s[ea].fa++;
}
}
int rt=0;
for(int i=0;i<n;++i)
{
if(s[i].fa==0)
{rt=i;break;}
}
memset(vis,0,sizeof vis);
dfs(rt);
printf("%d\n",min(dp[rt][0],dp[rt][1]));
}
}