1. 程式人生 > >UVA 1220 Party at Hali-Bula 最大獨立集

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;
}