uva 1220 lrj-P282 最大独立集(树形dp)

来源:互联网 发布:qualifier java 编辑:程序博客网 时间:2024/06/06 17:34

题意:

给出一个树形结构,除了老板外,每一个员工都有直属上司,在其中挑选了员工,就不能挑选他的上司

问这样的挑选方法最多可以挑选多少人,方案是否唯一

题解:

仔细划分即可

当前节点若选入,那么子节点都不能选入,并且当所有子节点都唯一的时候当前节点唯一

当前节点若不选,那么子节点可选可不选,并且当选入的子节点都唯一的时候当前点唯一,或者某个子节点选或者不选都是一样的时候不唯一



#include<map>#include<vector>#include<string>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define maxn 210map<string,int>mp;vector<int>sons[maxn];int dp[maxn][3],f[maxn][3];void dfs(int u){    if(sons[u].empty()) {dp[u][0]=0,dp[u][1]=1;return ;}    for(int i=0;i<sons[u].size();i++){        int k=sons[u][i];        dfs(k);        dp[u][1]+=dp[k][0];        if(f[k][0]) f[u][1]=1;        if(dp[k][0]==dp[k][1]){dp[u][0]+=dp[k][1],f[u][0]=1;}        else if(dp[k][0]>dp[k][1]){            dp[u][0]+=dp[k][0];            if(f[k][0]) f[u][0]=1;        }        else{            dp[u][0]+=dp[k][1];            if(f[k][1]) f[u][0]=1;        }    }    dp[u][1]++;}int main(){    int n,a,b;    char str1[110],str2[110];    //freopen("in.txt","r",stdin);    while(scanf("%d",&n),n)    {        mp.clear();        for(int i=0;i<maxn;i++)            sons[i].clear();        memset(f,0,sizeof(f));        memset(dp,0,sizeof(dp));        int cnt=2;        scanf("%s",str1);        mp[str1]=1;        for(int i=2;i<=n;i++){            scanf("%s%s",str1,str2);            a=mp[str1];            b=mp[str2];            if(!a) mp[str1]=cnt,a=cnt++;            if(!b) mp[str2]=cnt,b=cnt++;            sons[b].push_back(a);        }        dfs(1);        if(dp[1][0]==dp[1][1]){printf("%d No\n",dp[1][0]);}        else if(dp[1][0]>dp[1][1]){            printf("%d ",dp[1][0]);            if(f[1][0])    puts("No");            else           puts("Yes");        }        else{            printf("%d ",dp[1][1]);            if(f[1][1])    puts("No");            else           puts("Yes");        }    }    return 0;}


原创粉丝点击