hdu 2412 树形DP

思路:对于最大的人数很容易想到,就直接dp。但对于最大值是否唯一就需要应用辅助数组,isOnly[i][0]表示dp[i][0]是否唯一,同理isOnly[i][1]。

那么当(dp[v][0]>dp[v][1]&&isOnly[v][0]==0)或(dp[v][1]>dp[v][0]&&isOnly[v][1]==0)或(dp[v][1]==dp[v][0]),那么isOnly[u][0]=0;

如果isOnly[v][0]==0,那么isOnly[u][1]=0;

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<map>
#define Maxn 210
using namespace std;
int vi[Maxn],dp[Maxn][2],n,isOnly[Maxn][2];
vector <int> head[Maxn];
map <string,int> q;
void init()
{
    memset(vi,0,sizeof(vi));
    memset(dp,0,sizeof(dp));
    for(int i=0;i<=n;i++)
        head[i].clear();
    q.clear();
}
void add(int u,int v)
{
    head[u].push_back(v);
    head[v].push_back(u);
}
void dfs(int u)
{
    int i,v,sz;
    vi[u]=1;
    sz=head[u].size();
    dp[u][0]=0;
    dp[u][1]=1;
    isOnly[u][0]=isOnly[u][1]=1;
    for(i=0;i<sz;i++)
    {
        v=head[u][i];
        if(vi[v]) continue;
        dfs(v);
        dp[u][1]+=dp[v][0];
        dp[u][0]+=max(dp[v][1],dp[v][0]);
        if(dp[v][0]>dp[v][1]&&isOnly[v][0]==0) isOnly[u][0]=0;
        else if(dp[v][1]>dp[v][0]&&isOnly[v][1]==0) isOnly[u][0]=0;
        else if(dp[v][0]==dp[v][1]) isOnly[u][0]=0;
        if(isOnly[v][0]==0) isOnly[u][1]=0;
    }
}
int main()
{
    int i,j,cnt=0;
    char str1[Maxn],str2[Maxn];
    while(scanf("%d",&n),n)
    {
        cnt=0;
        init();
        scanf("%s",&str1);
        q[str1]=++cnt;
        for(i=1;i<n;i++)
        {
            scanf("%s%s",&str1,&str2);
            if(!q[str1])
                q[str1]=++cnt;
            if(!q[str2])
                q[str2]=++cnt;
            add(q[str1],q[str2]);
        }
        dfs(1);
        if(dp[1][0]>dp[1][1]&&isOnly[1][0])
            printf("%d Yes
",dp[1][0]);
        else
        if(dp[1][1]>dp[1][0]&&isOnly[1][1])
            printf("%d Yes
",dp[1][1]);
        else
            printf("%d No
",max(dp[1][0],dp[1][1]));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/wangfang20/p/3249640.html