UVA1220Party at Hali-Bula(树的最大独立集 + 唯一性判断)
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=105116#problem/H
紫书P282
员工和直属老板只能选一个,最多选多少人
思路:d(u,0)表示以U为根的子树,不选u点,则子节点可选可不选,f(u,0)表示不选u的唯一性 (1表示唯一,0,表示不唯一)
d(u,1)以u为根的子树,选择u点,f(u,1)表示选择u的唯一性
转移方程:d(u,0) = sum{ max( d(v,0), d(v,1) ) },v是子节点,当d(v,0) == d(v,1) ,不唯一,或者选择的那个不唯一,则f(u,0)不唯一
d(u,1) = sum{ d(v,0) }, 当f(v,0)有一个不唯一,则不唯一
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
using namespace std;
const int MAX = ;
vector <int> son[MAX];
map<string, int> name;
int d[MAX][],f[MAX][];
void DP(int u)
{
if(son[u].size() == )
{
d[u][] = f[u][] = ;
d[u][] = ;
f[u][] = ;
return;
}
int c = (int) son[u].size();
for(int i = ; i < c; i++)
{
DP(son[u][i]);
}
int sum = ,flag = ;
for(int i = ; i < c; i++)
{
sum += d[ son[u][i] ][];
if(f[ son[u][i] ][] == )
flag = ;
}
if(flag)
f[u][] = ;
else
f[u][] = ;
d[u][] = max(d[u][], sum + );
sum = ,flag = ;
for(int i = ; i < c; i++)
{
if(d[ son[u][i] ][] > d[ son[u][i] ][])
{
sum += d[ son[u][i] ][] ;
if(f[ son[u][i] ][] == )
flag = ;
}
else if(d[ son[u][i] ][] < d[ son[u][i] ][])
{
sum += d[ son[u][i] ][];
if(f[ son[u][i] ][] == )
flag = ;
}
else
{
sum += d[ son[u][i] ][];
flag = ;
}
}
if(flag)
f[u][] = ;
else
f[u][] = ;
d[u][] = max(d[u][], sum);
}
int main()
{
int n,m;
char worker[],boss[];
while(scanf("%d", &n) != EOF && n)
{
for(int i = ; i < MAX; i++)
son[i].clear();
name.clear();
memset(d, , sizeof(d));
memset(f, , sizeof(f));
m = ;
scanf("%s", boss);
name[boss] = m++;
for(int i = ; i < n; i++)
{
scanf("%s%s",worker,boss);
if(name.count(worker) == ) //注意输入的处理
name[worker] = m++;
if(name.count(boss) == )
name[boss] = m++;
son[ name[boss] ].push_back( name[worker] );
}
DP();
if(d[][] > d[][])
{
printf("%d ", d[][]);
if(f[][])
printf("Yes\n");
else
printf("No\n");
}
else if(d[][] < d[][])
{
printf("%d ", d[][]);
if(f[][])
printf("Yes\n");
else
printf("No\n");
}
else
{
printf("%d ", d[][]);
printf("No\n");
}
}
return ;
}
UVA1220Party at Hali-Bula(树的最大独立集 + 唯一性判断)的更多相关文章
- UVa 1220 Hali-Bula的晚会(树的最大独立集)
https://vjudge.net/problem/UVA-1220 题意: 公司里有n个人形成一个树状结构,即除了老板以外每个员工都有唯一的直属上司.要求选尽量多的人,但不能同时选择一个人和他的直 ...
- POJ 2342 树的最大独立集
题意:在树的最大独立集的基础上,加上权值.求最大. 分析: 采用刷表的方式写记忆化,考虑一个点选和不选,返回方式pair 型. 首先,无根树转有根树,dp(root). 注意的是:u不选,那么他的子节 ...
- POJ 3342 Party at Hali-Bula (树形dp 树的最大独立集 判多解 好题)
Party at Hali-Bula Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5660 Accepted: 202 ...
- 求树的最大独立集,最小点覆盖,最小支配集 贪心and树形dp
目录 求树的最大独立集,最小点覆盖,最小支配集 三个定义 贪心解法 树形DP解法 (有任何问题欢迎留言或私聊&&欢迎交流讨论哦 求树的最大独立集,最小点覆盖,最小支配集 三个定义 最大 ...
- HDU - 1520 Anniversary party (树的最大独立集)
Time limit :1000 ms :Memory limit :32768 kB: OS :Windows There is going to be a party to celebrate t ...
- 虚拟树研究-CheckBox初步判断只能在第一列
//虚拟树研究-CheckBox初步判断只能在第一列 procedure TWindowsXPForm.XPTreeInitNode(Sender: TBaseVirtualTree; ParentN ...
- UVA - 1220 Party at Hali-Bula 树的最大独立集
题意: 给定n个人,存在上下级关系,每个人只有一个上级,求最大独立集.并判断最大独立集是否唯一 思路:d[i][0]表示以i为根的子树中,不选择第i个节点的最大独立集,f[i][0]表示以i为根的子 ...
- UVA-1220 Party at Hali-Bula (树的最大独立集)
题目大意:数的最大独立集问题.特殊在要求回答答案是否唯一. 题目分析:定义状态dp(i,1),dp(i,0)分别表示以i为根节点的子树选不选i最多可选的人数,f(i,1),f(i,0)分别表示以i为根 ...
- UVa 1220 (树的最大独立集) Party at Hali-Bula
题意: 有一棵树,选出尽可能多的节点是的两两节点不相邻,即每个节点和他的子节点只能选一个.求符合方案的最大节点数,并最优方案判断是否唯一. 分析: d(u, 0)表示以u为根的子树中,不选u节点能得到 ...
随机推荐
- 基于 URL 的权限控制
先不用框架,自己实现一下 数据库 /* SQLyog v10.2 MySQL - 5.1.72-community : Database - shiro *********************** ...
- 使用DataAnnotations实现数据验证
https://msdn.microsoft.com/zh-cn/library/system.componentmodel.dataannotations.aspx http://www.cnblo ...
- ASP.NET MVC3 Model验证总结(转)
推荐: ASP.NET MVC的Model元数据与Model模板:预定义模板 http://www.cnblogs.com/artech/archive/2012/05/02/model-meta ...
- usb驱动开发1之学习准备
此系列是http://blog.csdn.net/fudan_abc/博文的整理,同时加入了自己的理解.很敬佩fudan_abc的文章,仔细学习和分析受益很多.注:fundan_abc所分析linux ...
- 【转】【C#】判断两个文件是否相同
使用System.security.Cryptography.HashAlgorithm类为每个文件生成一个哈希码,然后比较两个哈希码是否相同 该哈希算法为一个文件生成一个小的二进制“指纹”,从统计学 ...
- java String.getBytes()编码问题——String.getBytes(charset)
String的getBytes()方法是得到一个字串的字节数组,这是众所周知的.但特别要注意的是,本方法将返回该操作系统默认的编码格式的字节数组.如果你在使用这个方法时不考虑到这一点,你会发现在一个平 ...
- Linux常用指令---ps(查看进程)
Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程信 ...
- iOS:实现图片的无限轮播之使用第三方库SDCycleScrollView
下载链接:github不断更新地址:https://github.com/gsdios/SDCycleScrollView #import "ViewController.h" # ...
- 阿里客户端工程师试题简析——Android应用的闪退(crash)分析
1. 问题描述 闪退(Crash)是客户端程序在运行时遭遇无法处理的异常或错误时而退出应用程序的表现,请从crash发生的原因分类与解决方法.在出现crash后如何捕捉并分析异常这两个问题给出自己的解 ...
- protobuf 文件级别优化
package IM.BaseDefine;option java_package = "com.mogujie.tt.protobuf";option optimize_for ...