poj3342树形dp

来源:互联网 发布:淘宝高跟鞋 编辑:程序博客网 时间:2024/03/29 00:36

和poj2342一样,只是加了判断最大值是否唯一。

当dp2【s】>=dp1【s】时,若dp1【x】==dp2【x】;则不唯一。因为父节点不去更优。儿子节点去和不去都一样。结果就不唯一了。

特殊考虑的是根节点,如果dp1【root】==dp2【root】 ,则不唯一,因为已经到根节点,不影响其他的点了。

此题还可以建单向边,因为给定的条件是老板在后面,

#include<cstdio>#include<cstring>#include<iostream>#include<vector>#include<string>#include<map>using namespace std;vector<int>V[220];map<string,int>M;int vis[220];int dp1[220];//去int dp2[220];//不去void init(){    for(int i=0;i<220;i++)      V[i].clear(),dp1[i]=1;    memset(dp2,0,sizeof(dp2));    memset(vis,0,sizeof(vis));    M.clear();}void dfs(int s){    vis[s]=1;    for(int i=0;i<(int)V[s].size();i++)    {        int x=V[s][i];        if(!vis[x])        {            dfs(x);            dp1[s]+=dp2[x];   //s去,则x不去。            dp2[s]+=max(dp1[x] , dp2[x]);   //s不去,则在s点加上x去或不去的最大值.            //printf("dp1[%d]=%d   dp2[%d]=%d\n",s,dp1[s],s,dp2[s]);        }    }}int main(){    //freopen("Input.txt","r",stdin);    int n,i;    while(scanf("%d",&n)&&n)    {        init();        string str1,str2;        int num=1;        cin>>str1;        M[str1]=num++;        for(i=1;i<n;i++)        {            cin>>str1>>str2;            if(!M[str1]) M[str1]=num++;            if(!M[str2]) M[str2]=num++;            V[M[str1]].push_back(M[str2]);            V[M[str2]].push_back(M[str1]);        }        dfs(1);        printf("%d ",max(dp1[1],dp2[1]));        bool flag=true;        for(i=1;i<=n;i++)        {            flag=true;            if(dp2[i]>=dp1[i])            {                for(int j=0;j<(int)V[i].size();j++)                {                    int x=V[i][j];                    if(dp2[x]==dp1[x])                    {                        flag=false;                        break;                    }                }            }            if(!flag) break;        }        if(dp2[1]==dp1[1]||!flag) puts("No");        else puts("Yes");//        puts("--------------------------------");//        for(i=1;i<=n;i++)//          printf("%d   %d\n",dp1[i],dp2[i]);    }    return 0;}


原创粉丝点击