uva1220树的最大独立集

题意:公司里除了老板,每个人都有一个直属上司,要求选尽量多的人,但不能同时选一个人和他的直属上司,问最多能选多少个人,以及在人数最多的情况下方案是否唯一。

思路:d[u][0]表示不选u点能得到的最大人数d[u][0]=sum{max(d[v][0],d[v][1])}

      d[u][1]表示选u点能得到的最大人数d[u][1]=sum{d[v][0]}

      f[u][0]表示不选u点能获得的最大人数方案是否唯一,1.d[v][0]=d[v][1],不唯一(用1表示不唯一)。2.选择d[v][0]且f[v][0]=1;选择d[v][1]且f[v][1]=1。

      f[u][1]表示选择u点能获得的最大人数方案是否唯一,f[v][0]=1时f[u][1]=1。

      dfs

#include<bits/stdc++.h>
using namespace std;

int d[204][2],f[205][2];
vector<int>child[205];

void dp(int u)
{
    if(child[u].size()==0)
    {
        d[u][1]=1;
        d[u][0]=0;
        return;
    }
    int len=child[u].size();
    for(int i=0;i<len;i++)
    {
        int a=child[u][i];
        dp(a);
        if(d[a][0]>d[a][1]){d[u][0]=d[u][0]+d[a][0];if(f[a][0]==1)f[u][0]=1;}
        if(d[a][1]==d[a][0]){d[u][0]=d[u][0]+d[a][0];f[u][0]=1;}//²»Î¨Ò»
        if(d[a][0]<d[a][1]){d[u][0]=d[u][0]+d[a][1];if(f[a][1]==1)f[u][0]=1;}
        d[u][1]=d[u][1]+d[a][0];
        if(f[a][0]==1)f[u][1]=1;
    }
    d[u][1]++;
}
int main()
{
    int n;
    cin>>n;
    while(n)
    {
        memset(f,0,sizeof(f));
        memset(d,0,sizeof(d));
        memset(child,0,sizeof(child));
        map<string,int>v;
        string s1,s2;
        cin>>s1;
        int num=1;
        v[s1]=num++;
        for(int i=0;i<n-1;i++)
        {
            cin>>s1>>s2;
            if(!v[s1])v[s1]=num++;
            if(!v[s2])v[s2]=num++;//񅧏
            child[v[s2]].push_back(v[s1]);
        }
        dp(1);
        int flag=0;
        if(d[1][1]>d[1][0])flag=1;
        cout<<d[1][flag]<<' ';
        if(f[1][flag]==1||d[1][0]==d[1][1])cout<<"No"<<endl;
        else cout<<"Yes"<<endl;
        cin>>n;
    }
    return 0;
}

 

posted @ 2016-07-18 16:11  哲贤  阅读(190)  评论(0编辑  收藏  举报