poj 3342

简单树形DP,父节点要么去要么不去;

res[i]=max(∑res[child[i]],∑res[child(child[i])]);

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
    int i,next;
}vert[201];
char name[201][20];
int head[201],res[201],go[201],nogo[201],N,count;
int find(char * str)
{
    int i;
    for(i=1;i<N;i++)
        if(strcmp(name[i],str)==0) return i;
    strcpy(name[N],str);
    return N++;
}
int add(int s,int t)
{
    vert[count].i=t;
    vert[count].next=head[s];
    return count++;
}
int GetRes(int root)
{
    int j,k,sum1=0,sum2=0;
    if(head[root]==0) 
    {
        res[root]=1;
        go[root]=1;  nogo[root]=0;
        return res[root];
    }
    for(j=head[root];j;j=vert[j].next)
    {
        sum1+=GetRes(vert[j].i);
        for(k=head[vert[j].i];k;k=vert[k].next)
            sum2+=res[vert[k].i];
    }

    go[root]=sum1;  
    nogo[root]=sum2+1;
    res[root]=go[root] > nogo[root] ? go[root] : nogo[root];

    return res[root];
}
int judge(int root)
{
    int j,k;
    if(head[root]==0) return 1;
    if(go[root]==nogo[root]) return 0;
    if(go[root]>nogo[root])
    {
        for(j=head[root];j;j=vert[j].next)
            if(!judge(vert[j].i)) return 0;
    }
    else
    {
        for(j=head[root];j;j=vert[j].next)
            for(k=head[vert[j].i];k;k=vert[k].next)
                if(!judge(vert[k].i)) return 0;
    }
    return 1;
}
int main()
{
    int i,k,n,s,t;
    char str1[20],str2[20];
    while(scanf("%d",&n) && n)
    {
        N=count=1;
        memset(head,0,sizeof(head));
        scanf("%s",str1);
        k=find(str1);
        for(i=1;i<n;i++) 
        {
            scanf("%s %s",str1,str2);
            s=find(str1);
            t=find(str2);
            head[t]=add(t,s);
        }
                printf("%d ",GetRes(k));
        if(judge(k)) printf("Yes\n");
        else printf("No\n");

    }
    return 0;
}
posted @ 2012-06-09 10:32  书山有路,学海无涯  阅读(319)  评论(0编辑  收藏  举报