POJ - 3342 Party at Hali-Bula 树形DP

来源:互联网 发布:西班牙运营商网络频段 编辑:程序博客网 时间:2024/05/16 15:27

题目大意:某公司有个聚会,要邀请员工来参加。要求员工和他的直系上司不能同时到这个聚会,问最多能邀请到多少人,有多种邀请方法时输出No

解题思路:用dp[i][1]表示邀请第i个人,dp[i][0]表示没有邀请第i个人
初始dp[i][1] = 1, dp[i][0] = 0
状态转移方程为
dp[i][1] = sum(dp[son][0]) son为i的下属
dp[i][0] = sum(max(dp[son][1],dp[son][0])),上司不去,下属不一定要去
判断是否有多种邀请方法,只要往回回溯就可以
因为只有dp[i][0]这种状态会出现两个值选最大值的情况,所以只要判断这种状态下,dp[son][0] 会不会等于dp[son][1]就可以了
如果相等了,就有多种邀请方式了

#include<cstdio>#include<cstring>#include<vector>#include<algorithm>#include<map>#include<string>#include<iostream>#include<queue>#define maxn 210using namespace std;int n, cnt, dp[maxn][2];vector<int> tree[maxn];map<string,int> Map;struct Node{    int num, statu;    Node() {}    Node(int n, int s) {        num = n;        statu = s;    }};void init() {    Map.clear();    cnt = 1;    for(int i = 0; i <= n; i++)        tree[i].clear();    string str1, str2;    cin >> str1;    Map[str1] = cnt++;    int x, y;    for(int i = 0; i < n - 1; i++) {        cin >> str1 >> str2;        if(!Map[str1])            Map[str1] = cnt++;        if(!Map[str2])            Map[str2] = cnt++;        x = Map[str1];        y = Map[str2];        tree[y].push_back(x);    }}void solve(int cur) {    int size = tree[cur].size();    dp[cur][1] = 1;    dp[cur][0] = 0;    for(int i = 0; i < size; i++) {        solve(tree[cur][i]);        dp[cur][1] += dp[tree[cur][i]][0];        dp[cur][0] += max(dp[tree[cur][i]][0], dp[tree[cur][i]][1]);    }}int main (){    while(cin >> n) {        if(!n)            break;        init();        solve(1);        queue<Node> q;        if(dp[1][0] == dp[1][1])            printf("%d No\n",dp[1][1]);        else {            if(dp[1][0] < dp[1][1]) {                q.push(Node(1,1));            }            else                 q.push(Node(1,0));            bool flag = false;            while(!q.empty()) {                Node t = q.front();                q.pop();                int s = t.statu, Num = t.num;                int size = tree[Num].size();                for(int i = 0; i < size; i++) {                    if(s == 1)                        q.push(Node(tree[Num][i],0));                    else {                        if(dp[tree[Num][i]][0] == dp[tree[Num][i]][1]) {                             flag = true;                            break;                        }                        else if(dp[tree[Num][i]][0] > dp[tree[Num][i]][1])                            q.push(Node(tree[Num][i],0));                        else                            q.push(Node(tree[Num][i],1));                    }                }                if(flag)                    break;            }            if(flag)                printf("%d No\n",max(dp[1][0],dp[1][1]));            else                printf("%d Yes\n", max(dp[1][0],dp[1][1]));        }    }    return 0;}
0 0