刚刚那个题的升级版,本来自己是套着那个的思路写的,还是字符串没处理好,转而用课件的解法了,后来搜到邝斌也是dp[i][0] dp[i][1]这么做的,发现自己的思维有漏洞dp[root][1]+=min(dp[u][0],dp[u][1]); 不是单纯的=dp[j][0] 忽略那个CE RE也算是1A了\(^o^)/~
不过这个题还是可以用最小点覆盖做==详见我的另一篇博客:弱校联萌十一大决战之强力热身D. Vertex Cover最小点覆盖【附cin加速代码】 dp比图论美丽多了==
/********
hdu1054
2015.12.27
218MS 1792K 1609 B
********/
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 1600
struct node
{
int from,to,next;
}edge[N*2];
int min(int a,int b)
{
if(a<b) return a;
return b;
}
char str[2000];
int head[N],tol,dp[N][2],n;
bool isroot[N];
void add(int a,int b)
{
edge[tol].from=a;edge[tol].to=b;edge[tol].next=head[a];head[a]=tol++;
}
void dfs(int root)
{
dp[root][0]=0;
dp[root][1]=1;
for(int i=head[root];i!=-1;i=edge[i].next)
{
int u=edge[i].to;
dfs(u);
dp[root][0]+=dp[u][1];
dp[root][1]+=min(dp[u][0],dp[u][1]);
}
}
int main()
{
// freopen("cin.txt","r",stdin);
while(~scanf("%d",&n))
{
tol=0;
memset(head,-1,sizeof(head));
memset(isroot,false,sizeof(isroot));
int a,b,t;
for(int i=0;i<n;i++)
{
scanf("%d:(%d) ",&a,&t);
// dp[i][0]=0;dp[i][1]=1;
// printf("a=%d t=%d ",a,t);
while(t--)
{
scanf("%d",&b);
add(a,b);
isroot[b]=true;
}
}
int r;
for(int i=0;i<n;i++)
{
if(!isroot[i])
{
dfs(i);
//printf("root=%d ",i);
r=i;
break;
}
}
// for(int i=0;i<n;i++) printf("i=%d dp[i][0]=%d dp[i][1]=%d\n",i,dp[i][0],dp[i][1]);
printf("%d\n",min(dp[r][0],dp[r][1]));
}
return 0;
}