POJ 3342 Party at Hali-Bula (树形dp 树的最大独立集 判多解 好题)

Party at Hali-Bula

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 5660   Accepted: 2022

Description

Dear Contestant,

I‘m going to have a party at my villa at Hali-Bula to celebrate my retirement from BCM. I wish I could invite all my co-workers, but imagine how an employee can enjoy a party when he finds his boss among the guests! So, I decide
not to invite both an employee and his/her boss. The organizational hierarchy at BCM is such that nobody has more than one boss, and there is one and only one employee with no boss at all (the Big Boss)! Can I ask you to please write a program to determine
the maximum number of guests so that no employee is invited when his/her boss is invited too? I‘ve attached the list of employees and the organizational hierarchy of BCM.

Best,

--Brian Bennett

P.S. I would be very grateful if your program can indicate whether the list of people is uniquely determined if I choose to invite the maximum number of guests with that condition.

Input

The input consists of multiple test cases. Each test case is started with a line containing an integer
n (1 ≤ n ≤ 200), the number of BCM employees. The next line contains the name of the Big Boss only. Each of the following
n-1 lines contains the name of an employee together with the name of his/her boss. All names are strings of at least one and at most 100 letters and are separated by blanks. The last line of each test case contains a single 0.

Output

For each test case, write a single line containing a number indicating the maximum number of guests that can be invited according to the required condition, and a word Yes or No, depending on whether the list of guests is unique
in that case.

Sample Input

6
Jason
Jack Jason
Joe Jack
Jill Jason
John Jack
Jim Jill
2
Ming
Cho Ming
0

Sample Output

4 Yes
1 No

Source

Tehran 2006

题目链接:http://poj.org/problem?id=3342

题目大意:一棵树,父亲和儿子不能同时选入同一个集合,现在求能选集合中元素个数最多的那个集合大小,并判断解是否唯一

题目分析:求树的最大独立集的问题,好题,也用了两次dp的思想,有点类似HDU 5282这题的思想

dp[i][0]表示不选第i个结点,集合大小的最大值

dp[i][1]表示选第i个结点,集合大小的最大值

对于此dp显然

dp[i][1] = dp[son][0]  选父亲则不能选儿子

dp[i][0] = max(dp[son][0], dp[son][1]) 不选父亲的话则值等于选儿子或者不选儿子里的较大值

s[i][1] == true 表示选第i个结点时有唯一解,false表示解不唯一

s[i][0] == true 表示不选第i个结点时有唯一解,false表示解不唯一

开始时设s[i][1],s[i][0]都为true,对于此dp,我们主要考虑父亲的解变成不唯一的情况

与第一个dp状态对应,分成选父亲和不选父亲两种情况

if(!s[son][0])  s[i][1] = false,意思是如果不选儿子时有多个解,则此时可以选父亲,选父亲也肯定有多个解

if(dp[son][0] == dp[son][1])  s[i][0] = false,如果选不选儿子的答案相同,显然不选父亲时有多个解,因为选不选儿子都可以

最后自叶子向根回溯求解判断即可,这题因为map没清零,wa了大半天。。。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <iostream>
using namespace std;
int const MAX = 300;
int n;
int dp[MAX][2];
bool s[MAX][2];
bool vis[MAX];
vector <int> vt[MAX];

void DFS(int fa)
{
    dp[fa][1] = 1;
    vis[fa] = true;
    s[fa][0] = true;
    s[fa][1] = true;
    int sz = vt[fa].size();
    for(int i = 0; i < sz; i++)
    {
        int son = vt[fa][i];
        if(!vis[son])
        {
            DFS(son);
            dp[fa][1] += dp[son][0];
            dp[fa][0] += max(dp[son][0], dp[son][1]);
            if(dp[son][0] == dp[son][1])
                s[fa][0] = false;
            if(!s[son][0])
                s[fa][1] = false;
        }
    }
    return;
}

int main()
{
    while(scanf("%d", &n) != EOF && n)
    {
        map <string, int> mp;
        for(int i = 0; i < MAX; i++)
            vt[i].clear();
        memset(vis, false, sizeof(vis));
        memset(dp, 0, sizeof(dp));
        int cnt = 0;
        string boss, fir, sec;
        cin >> boss;
        mp[boss] = cnt ++;
        for(int i = 0; i < n - 1; i++)
        {
            cin >> sec >> fir;
            if(!mp.count(fir))
                mp[fir] = cnt ++;
            if(!mp.count(sec))
                mp[sec] = cnt ++;
            vt[mp[fir]].push_back(mp[sec]);
        }
        DFS(0);
        if(dp[0][1] > dp[0][0] && s[0][1])
            printf("%d Yes\n", dp[0][1]);
        else if(dp[0][1] < dp[0][0] && s[0][0])
            printf("%d Yes\n", dp[0][0]);
        else
            printf("%d No\n", max(dp[0][0] , dp[0][1]));
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-07 05:28:16

POJ 3342 Party at Hali-Bula (树形dp 树的最大独立集 判多解 好题)的相关文章

POJ3398Perfect Service[树形DP 树的最大独立集变形]

Perfect Service Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 1518   Accepted: 733 Description A network is composed of N computers connected by N − 1 communication links such that any two computers can be communicated via a unique rou

POJ 2057 The Lost House 经典树形DP+贪心

题意:链接 方法:树形DP+贪心 解析:这是一道好题. 好首先要明确这题求的是什么? 名义上是期望值,而实际上就是找一条路径.什么路径呢?从根节点走遍所有的叶子节点所花费步数最短的路径. 明确了题意后该怎么做呢? 首先看我们需要什么? 目前有个根节点,我们需要知道从他向一个分支走,失败步数是多少,成功步数是多少? 那么怎么维护我们需要的东西呢? 首先我们先给他们起个名:suc,fai; 其次再给一个节点的叶子节点的个数起个名:son 起名完事之后我们就要更新了. 先谈叶子节点,显然叶子节点的su

树形DP+树状数组 HDU 5877 Weak Pair

1 //树形DP+树状数组 HDU 5877 Weak Pair 2 // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 3 // 这道题要离散化 4 5 #include <bits/stdc++.h> 6 using namespace std; 7 #define LL long long 8 typedef pair<int,int> pii; 9 const double inf = 12345678901234

hdu-4118 Holiday&#39;s Accommodation(树形dp+树的重心)

题目链接: Holiday's Accommodation Time Limit: 8000/4000 MS (Java/Others)     Memory Limit: 200000/200000 K (Java/Others) Problem Description Nowadays, people have many ways to save money on accommodation when they are on vacation.One of these ways is exc

poj 1655 and 3107 and 2378 树形dp(树的重心问题)

简单的树形dp,顺便学习了树的重心的概念,即以该点为根的树的最大子树的结点数最少. poj 1655: 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 20001; 7 int head[N]; 8 int balance[N]; 9 int child[N]; 10 int n, e; 11 12 struct

POJ 2342 &amp;&amp;HDU 1520 Anniversary party 树形DP 水题

一个公司的职员是分级制度的,所有员工刚好是一个树形结构,现在公司要举办一个聚会,邀请部分职员来参加. 要求: 1.为了聚会有趣,若邀请了一个职员,则该职员的直接上级(即父节点)和直接下级(即儿子节点)都不能被邀请 2.每一个员工都有一个兴奋值,在满足1的条件下,要使得邀请来的员工的兴奋值最高 输出最高的兴奋值. 简单的树形DP dp[i][1]:表示以i为根的子树,邀请节点i的最大兴奋值 dp[i][0]:表示以i为根的子树,不邀请节点i的最大兴奋值 先根据入度找出整棵树的根节点, 然后一次DF

POJ 1849 Two (树形dp 树的直径 两种方法)

Two Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 1232   Accepted: 619 Description The city consists of intersections and streets that connect them. Heavy snow covered the city so the mayor Milan gave to the winter-service a list of st

POJ 3398 / UVA 1218 Perfect Service 树形DP

树形DP Perfect Service Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 1378   Accepted: 668 Description A network is composed of N computers connected by N ? 1 communication links such that any two computers can be communicated via a uniqu

poj 2342 【Anniversary party】树形dp

题目传送门//res tp poj 题意 给出一棵有权树,求一个节点集的权值和,满足集合内的任意两点不存在边 分析 每个点有选中与不选中两种状态,对于第\(i\)个点,记选中为\(sel_i\),不选中为\(insel_i\) 若某一节点选中,则其子节点都不能选中. 若某一节点不选中,则其子节点有两种选择:1.选中 2.不选中 故 \[sel_i = val_i +\sum_j insel_j\] \[insel_i = \sum_j max\{insel_j,sel_j\}\] 其中\(j\)