UVa 1220 - Party at Hali-Bula(树形DP)
链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3661
题意:
公司里有n(n≤200)个人形成一个树状结构,即除了老板之外每个员工都有唯一的直属上司。
要求选尽量多的人,但不能同时选择一个人和他的直属上司。问:最多能选多少人,以及在人数最多的前提下方案是否唯一。
分析:
本题几乎就是树的最大独立集问题,不过多了一个要求:判断唯一性。
一、设d(u,0)和f(u,0)表示以u为根的子树中,不选u点能得到的最大人数以及方案唯一性(f(u,0)=1表示唯一,0表示不唯一)。
二、设d(u,1)和f(u,1)表示以u为根的子树中,选u点能得到的最大人数以及方案唯一性。相应地,状态转移方程也有两套。
三、d(u,1)的计算:因为选了u,所以u的子结点都不能选,故d(u,1) = sum{d(v,0) | v是u的子结点}。当所有f(v,0)=1时f(u,1)=1。
四、d(u,0)的计算:因为u没有选,所以每个子结点v可选可不选,即d(u,0) = sum{ max(d(v,0), d(v,1)) }。
什么情况下方案是唯一的呢?首先,如果某个d(v,0)和d(v,1)相等,则不唯一;
其次,如果max取到的那个值对应的f=0,方案也不唯一(如d(v,0) > d(v,1) 且f(v,0)=0,则f(u,0)=0)。
代码:
#include <cstdio>
#include <map>
#include <string>
#include <vector>
using namespace std; const int UP = + ;
int cid, d[UP][]; // d数组表示以f为根的子树中,选或不选f点能得到的最大人数
bool u[UP][]; // u数组表示以f为根的子树中,选或不选f点的方案唯一性
map<string, int> M;
vector<int> son[UP]; int id(char* s){
if(M.count(s)) return M[s];
return M[s] = cid++;
} int dp(int f, int p){
d[f][p] = p;
u[f][p] = true;
for(int i = ; i < son[f].size(); i++){
int b = son[f][i];
if(p == ){
d[f][] += dp(b, );
if(!u[b][]) u[f][] = false;
}
else{
d[f][] += max(dp(b, ), dp(b, ));
if(d[b][] == d[b][]) u[f][] = false;
else if(d[b][] > d[b][] && !u[b][]) u[f][] = false;
else if(d[b][] > d[b][] && !u[b][]) u[f][] = false;
}
}
return d[f][p];
} int main(){
int n;
char f[], b[];
while(scanf("%d", &n) && n){
cid = ; M.clear();
for(int i = ; i < n; i++) son[i].clear(); scanf("%s", f); id(f);
for(int i = ; i < n; i++){
scanf("%s%s", b, f);
son[id(f)].push_back(id(b));
} printf("%d ", max(dp(, ), dp(, )));
bool ok = (d[][]>d[][]&&u[][]) || (d[][]>d[][]&&u[][]);
printf("%s\n", ok ? "Yes" : "No");
}
return ;
}
UVa 1220 - Party at Hali-Bula(树形DP)的更多相关文章
- UVa 1220 Party at Hali-Bula (树形DP,最大独立集)
题意:公司有 n 个人形成一个树形结构,除了老板都有唯一的一个直系上司,要求选尽量多的人,但不能同时选一人上和他的直系上司,问最多能选多少人,并且是不是唯一的方案. 析:这个题几乎就是树的最大的独立集 ...
- UVA - 1220 Party at Hali-Bula (树形DP)
有 n 个员工,n-1个从属关系. 不能同时选择某个员工和他的直接上司,问最多可以选多少人,以及选法是否唯一. 树上的最大独立集问题.只不过多了一个判断唯一性. dp[u][0]表示不选这个点的状态, ...
- 【UVA 1380】 A Scheduling Problem (树形DP)
A Scheduling Problem Description There is a set of jobs, say x1, x2,..., xn <tex2html_verbatim_ ...
- UVA Live Archive 4015 Cave (树形dp,分组背包)
和Heroes Of Might And Magic 相似,题目的询问是dp的一个副产物. 距离是不好表示成状态的,但是可以换一个角度想,如果知道了从一个点向子树走k个结点的最短距离, 那么就可以回答 ...
- UVa 10859 - Placing Lampposts 树形DP 难度: 2
题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...
- UVA - 1218 Perfect Service(树形dp)
题目链接:id=36043">UVA - 1218 Perfect Service 题意 有n台电脑.互相以无根树的方式连接,现要将当中一部分电脑作为server,且要求每台电脑必须连 ...
- 树形DP UVA 1292 Strategic game
题目传送门 /* 题解:选择一个点,它相邻的点都当做被选择,问最少选择多少点将所有点都被选择 树形DP:dp[i][0/1]表示当前点选或不选,如果选,相邻的点可选可不选,取最小值 */ /***** ...
- uva 1292 树形dp
UVA 1292 - Strategic game 守卫城市,城市由n个点和n-1条边组成的树,要求在点上安排士兵,守卫与点相连的边.问最少要安排多少士兵. 典型的树形dp.每一个点有两个状态: dp ...
- UVA 1484 - Alice and Bob's Trip(树形DP)
题目链接:1484 - Alice and Bob's Trip 题意:BOB和ALICE这对狗男女在一颗树上走,BOB先走,BOB要尽量使得总路径权和大,ALICE要小,可是有个条件,就是路径权值总 ...
随机推荐
- 深入理解JavaScript系列(42):设计模式之原型模式
介绍 原型模式(prototype)是指用原型实例指向创建对象的种类,并且通过拷贝这些原型创建新的对象. 正文 对于原型模式,我们可以利用JavaScript特有的原型继承特性去创建对象的方式,也就是 ...
- Java并发编程之volatile关键字解析
一内存模型的相关概念 二并发编程中的三个概念 三Java内存模型 四深入剖析volatile关键字 五使用volatile关键字的场景 volatile这个关键字可能很多朋友都听说过,或许也都用过.在 ...
- 在 Web 应用中创建 Node.js 应用程序
本分步指南将通过 Azure Web 应用帮助您启动并运行示例 Node.JS 应用程序.除 Node.JS 外,Azure Web 应用还支持其他语言,如 PHP..NET.Node.JS.Pyth ...
- rabbit工作队列模式
工作队列比简单队列在消费者这边多了一个方法. channel.basicQos(1);公平队列消费(参数设置为1,表示消费者消费完一条才会去接受再次发来的消息) 生产者: package com.kf ...
- Java基础(9)——数组
难点儿的已经过去啦,现在又开始基础了哈~ 之前讲变量的时候,变量是一个个的呀~,那我要搞一串变量该啷个办呢?Java给我们出了个好东西叫数组(*^▽^*) 数组呢,就是将变量一组一组的存起来,这个也是 ...
- 2、springboot返回json
新建maven项目 添加依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId ...
- webapp 的简单开发
web app 的技术平台很多,如adobe phonegap.sencha touch.appcan(国产).dcloud(国产)平台.我选择了dcloud平台,原因:简单,容易上手. web ap ...
- webstorm添加自定义代码块
widnow下使用alt+ctrl+s 调出setting面板 mac下使用command+,(逗号)调出Preferences面板 搜索live template选中js,在javascrpt 模板 ...
- Apache服务器运维笔记(3)----容器部分
1.<IfModule>容器 <IfModule>容器作用于模块,它会首先判断模块是否载入,然后再决定是否进行处理,也就是说只有当判断结果为真时才会执行容器内的指令,相反如果为 ...
- JavaScript中的appendChild()方法
appendChild()方法是向节点添加最后一个子节点.也可以使用此方法从一个元素向另一个元素移动元素. 案例一:向节点添加最后一个子节点 <!DOCTYPE html> <htm ...