UVA 1220 Party at Hali-Bula 最大独立集

题意:

n个人形成一个树形结构,除了老板外每个员工都有唯一的直属上司,要求选择尽量多的人,但不能同时选择一个人和他的直属上司,问最多能选多少人,以及人数最多的前提下方案是否唯一。

分析:

d(u,0)表示以u为根的子树中,不选u点(1表示选择u点)能得到的最大人数
f(u,0)=1表示唯一,f(u,0)=0表示不唯一

/*
d(u,0)表示以u为根的子树中,不选u点(1表示选择u点)能得到的最大人数
f(u,0)=1表示唯一,f(u,0)=0表示不唯一
*/

#include<bits/stdc++.h>

using namespace std;

const int maxn=220;

int cnt;
vector<int> g[maxn];
int n,d[maxn][2],f[maxn][2];

map<string,int> mp;

int ID(const string& s){
    if(!mp[s]) mp[s]=++cnt;
    return mp[s];
}

int dp(int u,int k){
    f[u][k]=1;
    d[u][k]=k;
    for(int i=0;i<g[u].size();i++){
        int v=g[u][i];
        if(k==1){   //因为k==1代表唯一,所以u节点必须取
            d[u][1]+=dp(v,0);
            if(!f[v][0]) f[u][1]=0;
        }else{
            d[u][0]+=max(dp(v,0),dp(v,1));
            if(d[v][0]==d[v][1]) f[u][k]=0;
            else if(d[v][0]>d[v][1]&&!f[v][0]) f[u][k]=0;
            else if(d[v][1]>d[v][0]&&!f[v][1]) f[u][k]=0;
        }
    }
    return d[u][k];
}

int main(){
    string s,s2;
    while(cin>>n,n){
        cin>>s;
        cnt=0;
        mp.clear();
        for(int i=0;i<=n;i++) g[i].clear();
        ID(s);
        for(int i=0;i<n-1;i++){
            cin>>s>>s2;
            g[ID(s2)].push_back(ID(s));
        }
        printf("%d ",max(dp(1,0),dp(1,1)));
        bool flag=false;
        if(d[1][0]>d[1][1]&&f[1][0]) flag=1;
        if(d[1][1]>d[1][0]&&f[1][1]) flag=1;
        if(flag) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40679299/article/details/83718892