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\n",dp[1][0]);

        else

        if(dp[1][1]>dp[1][0]&&isOnly[1][1])

            printf("%d Yes\n",dp[1][1]);

        else

            printf("%d No\n",max(dp[1][0],dp[1][1]));

    }

    return 0;

}

 

你可能感兴趣的:(HDU)