刚刚那个题的升级版,本来自己是套着那个的思路写的,还是字符串没处理好,转而用课件的解法了,后来搜到邝斌也是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;
}