hdu2412树形dp

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
int son1[205],f[205][205],dp[205][2],dup[205][2],hash[205];
char s[205][105],s1[105],s2[105];
void dfs(int k)
{
    if (hash[k]==1) return;
    if (son1[k]==0) {dp[k][0]=0; dp[k][1]=1; dup[k][0]=dup[k][1]=1; hash[k]=1; return;}
    dp[k][1]+=1;
    dup[k][0]=dup[k][1]=1;
    for (int i=1;i<=son1[k];i++)
    {
        dfs(f[k][i]);
        dp[k][0]+=max(dp[f[k][i]][0],dp[f[k][i]][1]);
        dp[k][1]+=dp[f[k][i]][0];
        if (dp[f[k][i]][0]>dp[f[k][i]][1]&&dup[f[k][i]][0]==0) dup[k][0]=0;
        else if (dp[f[k][i]][0]<dp[f[k][i]][1]&&dup[f[k][i]][1]==0) dup[k][0]=0;
        else if (dp[f[k][i]][0]==dp[f[k][i]][1]) dup[k][0]=0;
        if (dup[f[k][i]][0]==0) dup[k][1]=0;
    }
    hash[k]=1;
    return;
}
int main()
{
    int i,j,n,sum,ans1,ans2;
    while (~scanf("%d",&n)&&n!=0)
    {
        getchar();
        scanf("%s",s[0]); sum=0;
        memset(son1,0,sizeof(son1));
        for (i=1;i<n;i++)
        {
            getchar();
            scanf("%s %s",s1,s2);
            ans1=ans2=-1;
            for (j=0;j<=sum;j++)
            {
                if (strcmp(s[j],s1)==0) ans1=j;
                if (strcmp(s[j],s2)==0) ans2=j;
            }
            if (ans1!=-1&&ans2!=-1) {son1[ans2]++; f[ans2][son1[ans2]]=ans1; }
            else if (ans2!=-1) {sum++; strcpy(s[sum],s1); son1[ans2]++; f[ans2][son1[ans2]]=sum; }
            else if (ans1!=-1) {sum++; strcpy(s[sum],s2); son1[sum]++; f[sum][son1[sum]]=ans1;}
            else {sum+=2; ans1=sum; strcpy(s[sum],s1); ans2=sum-1;strcpy(s[sum-1],s2); son1[ans2]++; f[ans2][son1[ans2]]=ans1; }
        }
  /*      for (i=0;i<=sum;i++)
        {
            printf("%d",i);
            for (j=1;j<=son1[i];j++) printf(" %d",f[i][j]);
            printf("\n");
        }*/
        memset(hash,0,sizeof(hash));
        memset(dp,0,sizeof(dp));
        memset(dup,0,sizeof(dup));
        for (i=sum;i>=0;i--) dfs(i);
        printf("%d ",max(dp[0][0],dp[0][1]));
        if (dp[0][0]>dp[0][1]&&dup[0][0]==1) printf("Yes\n");
        else if (dp[0][0]<dp[0][1]&&dup[0][1]==1) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

http://acm.hdu.edu.cn/showproblem.php?pid=2412

posted on 2014-07-16 14:25  xiao_xin  阅读(120)  评论(0编辑  收藏  举报

导航