UVa 1220 Party at Hali-Bula (树形DP,最大独立集)

题意:公司有 n 个人形成一个树形结构,除了老板都有唯一的一个直系上司,要求选尽量多的人,但不能同时选一人上和他的直系上司,问最多能选多少人,并且是不是唯一的方案。

析:这个题几乎就是树的最大的独立集问题,只不过多一个判断唯一性而已。用两个数组,一个用来记录人数,一个用来判断唯一性。

d[u][0],表示以 u 为根的子树中,不选 u 点能够得到最大人数,那么d[u][1]就是选 u 点能达到最大人数。

f[u][0]类似,表示以 u 为根的子树中,不选 u 点是否唯一,那么f[u][1]就是选 u 点是否唯一。

对于d[u][1]的计算,因为选择了 u,那么 u 的子结点都不能选,所以就是 d[u][1] = sum(d[v][0], v是子结点),当f[v][0] 是不唯一时,f[u][1] 也不唯一。

对于d[u][0]的计算,因为没有选择了 u,那么它的子结点可以选也可以不选,也就是选最大的,即d[u][0] = sum(max(d[v][0], d[v][1])),那么这个唯一性怎么判断呢?和上面差不多,

就多了一个,如果d[v][0] == d[v][1],那么这个就是不唯一的了,其他的和上面一样。剩下的就简单了,用DFS即可。

代码如下:

#include <iostream>
#include <cstdio>
#include <map>
#include <cstring>
#include <vector>

using namespace std;
const int maxn = 200 + 5;
vector<int> G[maxn];
bool f[maxn][2];
int d[maxn][2], n, cnt;//d[u][0] 不选 ,d[u][0] 选
map<string, int> id;

void init(){//初始化
    for(int i = 1; i <= n; ++i)  G[i].clear();
    memset(f, false, sizeof(f));
    memset(d, 0, sizeof(d));
    cnt = 0;   id.clear();
}

int getid(const string &s){//获得id
    if(id.count(s))   return id[s];
    return id[s] = ++cnt;
}

void dfs(int u){
    if(!G[u].size()){//最下端
        d[u][0] = 0;
        d[u][1] = 1;
        return ;
    }

    for(int i = 0; i < G[u].size(); ++i){
        int son = G[u][i];
        dfs(son);
        d[u][1] += d[son][0];//d[u][1]的计算
        if(f[son][0])   f[u][1] = true;//判断唯一性
        if(d[son][0] > d[son][1]){//d[u][0]的计算
            d[u][0] += d[son][0];
            if(f[son][0])  f[u][0] = true;
        }
        else if(d[son][0] == d[son][1]){//相等,那就不唯一
            d[u][0] += d[son][0];
            f[u][0] = true;
        }
        else {
            d[u][0] += d[son][1];
            if(f[son][1])  f[u][0] = true;
        }
    }
    ++d[u][1];//别忘了加1
}

int main(){
    while(scanf("%d", &n) == 1 && n){
        init();
        string s1, s2;
        cin >> s1;  getid(s1);
        for(int i = 0; i < n-1; ++i){
            cin >> s1 >> s2;
            G[getid(s2)].push_back(getid(s1));
        }

        dfs(1);
        if(d[1][0] == d[1][1])  printf("%d No\n", d[1][0]);//判断谁在数更大
        else if(d[1][0] > d[1][1])  printf("%d %s\n", d[1][0], f[1][0] ? "No" : "Yes");
        else  printf("%d %s\n", d[1][1], f[1][1] ? "No" : "Yes");
    }
    return 0;
}
时间: 2024-10-15 04:29:42

UVa 1220 Party at Hali-Bula (树形DP,最大独立集)的相关文章

UVA 11174 Stand in a Line 树形dp+计数

题目链接:点击打开链接 题意:白书的P103. 加个虚根就可以了...然后就是一个多重集排列. import java.io.PrintWriter; import java.util.ArrayList; import java.util.Scanner; public class Main { static int N = 40100; ArrayList<Integer>[] G = new ArrayList[N]; static long mod = 1000000007; long

UVa 1220 Hali-Bula的晚会(树的最大独立集)

https://vjudge.net/problem/UVA-1220 题意: 公司里有n个人形成一个树状结构,即除了老板以外每个员工都有唯一的直属上司.要求选尽量多的人,但不能同时选择一个人和他的直属上司.输出最多能选多少人并判断是否唯一. 思路: 树的最大独立集问题.就是需要额外判定是否是唯一的. 因为输入的都是人名,所以首先就是用map容器来处理,上下属的关系就用vector容器来处理. d[u][1]表示以u为根的子树中,选u点能得到的最大人数,f[u][1]判断这种方案是否唯一. d[

uva 1220 - Party at Hali-Bula 【入门树形dp】

题目:uva 1220 - Party at Hali-Bula 题意:一个公司员工要举行聚会,要求任意一个人不能和他的直接上司同时到场,一个员工只有一个支系上司,现在求最多有多少人到场,并且方案是否唯一 分析:分析发现是要求一个树的最大独立集.这里可以用树形dp解决. 定义dp[x][0]:表示在 i 点不选 i 点的以 x 为子树的最大独立集 而dp[x][1] 表示x到场的最大独立集 定义f [x][0]:表示以x为根且x点不选的子树是否唯一 ,f[x][1]表示以x为根且x选的子树是否唯

Party at Hali-Bula UVA - 1220 (树形dp)

Party at Hali-Bula UVA - 1220 题意:选一个公司的人去参加晚会,要求不能选有直接上下级关系的人,问最多选多少人去,并判断方案是否唯一. 树的最大独立集,并判断是否唯一. d[u][1]表示选u,d[u][0]表示不选u f[u][1]==1表示选u的情况下唯一,f[u][1]==0表示不唯一 f[u][0]为不选u的情况下的唯一性 1 #include <cstdio> 2 #include <bits/stdc++.h> 3 using namespa

UVA - 1218 Perfect Service(树形dp)

题目链接:id=36043">UVA - 1218 Perfect Service 题意 有n台电脑.互相以无根树的方式连接,现要将当中一部分电脑作为server,且要求每台电脑必须连接且仅仅能连接一台server(不包含作为server的电脑).求最少须要多少台电脑作为server. 思路 典型的树形dp问题,那么我们来建立模型. d(u,0):u是server,孩子是不是server均可 d(u,1):u不是server,u的父亲是server,u的孩子不能是server d(u,2)

uva 12186 Another Crisis 树形dp

// uva 12186 Another Crisis 树形dp // // 对于一个节点u,有k个子节点,则至少有c = (k * T - 1) / 100 + 1才能 // 发信,即c / k >= T / 100,则 c 的值为 k * T /100,上取整变成上式 // 将所有的子节点d从小到大排序,取前c个就是d[u]的值 // 紫书上的一题,之前看了好久好久,觉得挺好的,然而一直没做,今天就来 // 体验体验,挺好的一题,注意一下,如果一个节点是叶节点,直接return 1就好 //

uva 1484 - Alice and Bob&#39;s Trip(树形dp)

题目链接:uva 1484 - Alice and Bob's Trip 题目大意:Alice和Bob小两口一起出去旅行,他们从0城市出发,Bob喜欢走比较远的路,因为他是个勤奋的好孩子,Alice喜欢走比较近的路,因为她是一个不勤奋的坏孩子,所以有了意见上的分歧,于是乎在出门前他们约法三章,要求说最后的距离值在[l,r]之间,并且由夫妻两轮流做决定,决定说下一个城市去哪里.现在给出n个城市,以及n-1条边,问说在不让Bob媳妇生气的情况下,Bob最远能走多远(不违反约定),如果无法做到不违反约

uva 10859 Placing Lampposts,树形dp

// uva 10859 Placing Lampposts // 树形dp // // 题目的意思是一个无向无环图中,有一些顶点和一些边 // 要在顶点上放置灯笼(灯笼可以照亮与它相邻接的点), // 使得所有的边都能被灯笼照亮,其中可能有一些边被两个灯笼 // 照亮,则要求使得所有边都被灯笼照亮所需灯笼的最小值, // 并且,此时边同时被两个灯笼照亮的数目应尽可能的多 // // 思路是 // d[i][0]表示在节点i不放置灯笼所需的灯笼的最小值 // d[i][1]表示在节点i放置灯笼所

UVA 12186 Another Crisis(树形DP)

A couple of years ago, a new world wide crisis started, leaving many people with economical problems. Some workers of a particular company are trying to ask for an increase in their salaries. The company has a strict hierarchy, in which each employee