【POJ - 3342】Party at Hali-Bula(树形dp,最大独立集,是否有唯一解)

题干:

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

题目大意:

在一个公司中要举办一个聚会,每一个员工有一个奉献值。为了和谐规定直接上下级不能一起出席。

解题报告:

   这道题麻烦的地方在于需要判断是否方案数唯一。。。首先你要知道我们的答案中一定每个顶点都用到了dp[][0]或者dp[][1]这两个状态中的一个,所以你就想,,(假设父节点u子节点v)如果我当前节点用的是dp[u][1],那么对于子节点就制造不出矛盾,如果我用的是dp[u][0],那么我们就可以看子节点是否有矛盾(因为这时候子节点是可以选择的),如果我选和不选都可以取到max,那么矛盾就出来了。(有的同学会问,你这一个点取到max有啥用,万一我不取这一分支呢,但是其实是不存在这种顾虑的,因为你是dp啊,有更大的值肯定会选啊,,其实究其原因还是那句“最终的答案中一定每个顶点都用到了dp[][0]或者dp[][1]这两个状态中的一个”,,所以这俩状态哪个更大我肯定会取这个值,,(好吧其实还是用一个标记数组直接递推上去比较靠谱))

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
map<string,int> mp;
vector<int >vv[505];
char s[205],s1[205],s2[205];
int dp[505][2];
int haha;
void dfs(int cur,int root) {dp[cur][1]=1;int up = vv[cur].size();for(int i = 0; i<up; i++) {int v = vv[cur][i];if(v == root) continue;dfs(v,cur);dp[cur][1] += dp[v][0];dp[cur][0] += max(dp[v][0],dp[v][1]);}for(int i = 0; i<up; i++) {int v = vv[cur][i];if(v == root) continue;if(dp[cur][0] > dp[cur][1] && dp[v][0] == dp[v][1]) haha=0;}
}
int main()
{int n,tot;while(~scanf("%d",&n)) {if(n == 0) break; haha=1;mp.clear();for(int i = 1; i<=n; i++) vv[i].clear();memset(dp,0,sizeof dp);tot=0;scanf("%s",s);mp[s] = ++tot;for(int i = 1; i<=n-1; i++) {scanf("%s%s",s1,s2);if(mp.find(s1) == mp.end()) mp[s1] = ++tot;if(mp.find(s2) == mp.end()) mp[s2] = ++tot;int t1=mp[s1],t2=mp[s2];vv[t1].pb(t2);vv[t2].pb(t1);}dfs(1,0);printf("%d ",max(dp[1][0],dp[1][1]));if(dp[1][0] == dp[1][1]) haha=0;if(haha == 1) printf("Yes");else printf("No");printf("\n");}return 0 ;}

 

错误代码1:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
map<string,int> mp;
vector<int >vv[505];
char s[205],s1[205],s2[205];
int dp[505][2];
int qq[505];
int forbid;
void dfs(int cur,int root) {if(cur != forbid)dp[cur][1]=1;int up = vv[cur].size();for(int i = 0; i<up; i++) {int v = vv[cur][i];if(v == root) continue;dfs(v,cur);if(cur != forbid) dp[cur][1] += dp[v][0];dp[cur][0] += max(dp[v][0],dp[v][1]);}
}
int main()
{int n,tot;while(~scanf("%d",&n)) {if(n == 0) break; forbid=-1;mp.clear();for(int i = 1; i<=n; i++) vv[i].clear();memset(dp,0,sizeof dp);memset(qq,0,sizeof qq);tot=0;scanf("%s",s);mp[s] = ++tot;for(int i = 1; i<=n-1; i++) {scanf("%s%s",s1,s2);if(mp.find(s1) == mp.end()) mp[s1] = ++tot;if(mp.find(s2) == mp.end()) mp[s2] = ++tot;int t1=mp[s1],t2=mp[s2];vv[t1].pb(t2);vv[t2].pb(t1);}dfs(1,0);printf("%d ",max(dp[1][0],dp[1][1]));int ans = max(dp[1][0],dp[1][1]);int cnt = 0;for(int i = 1; i<=n; i++) {forbid = i;if(max(dp[1][0],dp[1][1]) == ans) cnt++;}if(cnt == 1) printf("Yes");else printf("No");printf("\n");}return 0 ;}

错误代码2:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
map<string,int> mp;
vector<int >vv[505];
char s[205],s1[205],s2[205];
int dp[505][2];
int qq[505];
int haha;
void dfs(int cur,int root) {dp[cur][1]=1;int up = vv[cur].size();for(int i = 0; i<up; i++) {int v = vv[cur][i];if(v == root) continue;dfs(v,cur);dp[cur][1] += dp[v][0];dp[cur][0] += max(dp[v][0],dp[v][1]);}
}
void DFS(int cur,int root,int res) {if(res == 1) haha++;int up = vv[cur].size();for(int i = 0; i<up; i++) {int v = vv[cur][i];if(v == root) continue;if(max(dp[v][0],dp[v][1]) == res-1)DFS(v,cur,res-1);}
}
int main()
{int n,tot;while(~scanf("%d",&n)) {if(n == 0) break; haha=0;mp.clear();for(int i = 1; i<=n; i++) vv[i].clear();memset(dp,0,sizeof dp);memset(qq,0,sizeof qq);tot=0;scanf("%s",s);mp[s] = ++tot;for(int i = 1; i<=n-1; i++) {scanf("%s%s",s1,s2);if(mp.find(s1) == mp.end()) mp[s1] = ++tot;if(mp.find(s2) == mp.end()) mp[s2] = ++tot;int t1=mp[s1],t2=mp[s2];vv[t1].pb(t2);vv[t2].pb(t1);}dfs(1,0);printf("%d ",max(dp[1][0],dp[1][1]));int ans = max(dp[1][0],dp[1][1]);DFS(1,0,ans);
//		int cnt = 0;
//		for(int i = 1; i<=n; i++) {
//			if(max(dp[1][0],dp[1][1]) == ans) cnt++;
//		}
//		//printf("%d",mp["Jill"]);if(haha == 1) printf("No");else printf("Yes");printf("\n");}return 0 ;}

错误代码3:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
map<string,int> mp;
vector<int >vv[505];
char s[205],s1[205],s2[205];
int dp[505][2];
int qq[505];
int haha;
void dfs(int cur,int root) {dp[cur][1]=1;int up = vv[cur].size();for(int i = 0; i<up; i++) {int v = vv[cur][i];if(v == root) continue;dfs(v,cur);dp[cur][1] += dp[v][0];dp[cur][0] += max(dp[v][0],dp[v][1]);}
}
void DFS(int cur,int root,int res,bool cho) {//cho==0代表当前点没选			//ok==0代表当前点不能选 if(res == 1) {haha++;return ;}int up = vv[cur].size();for(int i = 0; i<up; i++) {int v = vv[cur][i];if(v == root) continue;//if(max(dp[v][0],dp[v][1]) == res-1)if(cho == 1) {if(dp[v][0] == res-1) DFS(v,cur,res-1,0);}else {if(dp[v][0] == res-1) DFS(v,cur,res-1,0);if(dp[v][1] == res-1) DFS(v,cur,res-1,1);}}
}
int main()
{int n,tot;while(~scanf("%d",&n)) {if(n == 0) break; haha=0;mp.clear();for(int i = 1; i<=n; i++) vv[i].clear();memset(dp,0,sizeof dp);memset(qq,0,sizeof qq);tot=0;scanf("%s",s);mp[s] = ++tot;for(int i = 1; i<=n-1; i++) {scanf("%s%s",s1,s2);if(mp.find(s1) == mp.end()) mp[s1] = ++tot;if(mp.find(s2) == mp.end()) mp[s2] = ++tot;int t1=mp[s1],t2=mp[s2];vv[t1].pb(t2);vv[t2].pb(t1);}dfs(1,0);printf("%d ",max(dp[1][0],dp[1][1]));int ans = max(dp[1][0],dp[1][1]);if(dp[1][1] == ans) {DFS(1,0,ans,1);}if(dp[1][0] == ans) {DFS(1,0,ans,0);}
//		DFS(1,0,ans);
//		int cnt = 0;
//		for(int i = 1; i<=n; i++) {
//			if(max(dp[1][0],dp[1][1]) == ans) cnt++;
//		}
//		//printf("%d",mp["Jill"]);if(haha == 1) printf("Yes");else printf("No");printf("\n");}return 0 ;}

用二维数组标记的dfs(Orzwjh大佬)

void dfs(int rt)
{for(int i=head[rt];i!=-1;i=side[i].nex){int ty=side[i].v;dfs(ty);if(mk[ty][0]==1){mk[rt][1]=1;}dp[rt][1]+=dp[ty][0];if(dp[ty][0]==dp[ty][1]){dp[rt][0]+=dp[ty][0];mk[rt][0]=1;}else if(dp[ty][0]>dp[ty][1]){dp[rt][0]+=dp[ty][0];if(mk[ty][0]==1)mk[rt][0]=1;}else{dp[rt][0]+=dp[ty][1];if(mk[ty][1]==1)mk[rt][0]=1;}}
}

总结 记住了一直都是用孩子节点的值去更新父亲节点的值就好了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/441188.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安川西格玛7驱动器手册_什么是伺服驱动器?选型的原则有哪些?

头条号私信回复1&#xff0c;获取海量免费学习资源&#xff0c;内容包括自动化电气工程师必备的软件、电子书、视频教程等题图&#xff1a;伺服驱动器来源&#xff1a;百度图片什么是伺服驱动器&#xff1f;该如何选型&#xff1f;有哪些主流品牌&#xff1f;你想知道的全在这里…

java猜数游戏图形界面_Java做一个猜数的小游戏

Author &#xff1a; By Runsen效果展现猜数字游戏是一个简单&#xff0c;有趣的小游戏。游戏者通过输入一个指定区间的数字&#xff0c;与系统产生的随机数进行对比&#xff0c;然后输出相应的结果。游戏运行时产生一个0&#xff0d;10之间的随机整数&#xff0c;要求用户从控…

【CodeForces - 266C】Below the Diagonal (递归,子问题,贪心模拟)

题干&#xff1a; You are given a square matrix consisting of n rows and n columns. We assume that the rows are numbered from 1 to n from top to bottom and the columns are numbered from 1to n from left to right. Some cells (n - 1 cells in total) of the t…

python 0o_Python 中的比较:is 与 ==

在 Python 中会用到对象之间比较&#xff0c;可以用 &#xff0c;也可以用 is 。但是它们的区别是什么呢&#xff1f;is 比较的是两个实例对象是不是完全相同&#xff0c;它们是不是同一个对象&#xff0c;占用的内存地址是否相同。莱布尼茨说过&#xff1a;“世界上没有两片完…

python中long类型_浅谈python 四种数值类型(int,long,float,complex)

Python支持四种不同的数值类型,包括int(整数)long(长整数)float(浮点实际值)complex (复数),本文章向码农介绍python 四种数值类型,需要的朋友可以参考一下。 数字数据类型存储数值。他们是不可改变的数据类型,这意味着改变数字数据类型的结果,在一个新分配的对象的值。 N…

【CodeForces - 264A】Escape from Stones (模拟,卡精度的处理)

题干&#xff1a; Squirrel Liss lived in a forest peacefully, but unexpected trouble happens. Stones fall from a mountain. Initially Squirrel Liss occupies an interval [0, 1]. Next, nstones will fall and Liss will escape from the stones. The stones are nu…

python开发mbus程序_Python pywmbus包_程序模块 - PyPI - Python中文网

#WIP WM总线在Python中的实现本项目实施了无线m-bus标准的部分内容&#xff0c;定义见din en 13757-1及以下。目前&#xff0c;只支持未加密的短帧(即ci 0x7a)。欢迎拉取请求。##安装###点pip install pywmbus###手动git clone https://github.com/jalmeroth/pywmbus.gitcd pyw…

【CodeForces - 266B 】Queue at the School (模拟)

题干&#xff1a; During the break the schoolchildren, boys and girls, formed a queue of n people in the canteen. Initially the children stood in the order they entered the canteen. However, after a while the boys started feeling awkward for standing in fr…

查看git当前tag_Git - git tag - 查看当前分支 tag 版本说明

索引&#xff1a;参看代码 GitHub&#xff1a;一、示例&#xff1a;1 git tag -l -n二、说明:1."tag" 部分tag 代表的是标签动作,可以带参数 ,也可以不带参数,带上不同的参数可以实现标签的 新建/删除/查询/验证 等功能.2."-l" 部分-l 注意是字母"L&q…

【CodeForces - 270A】Fancy Fence (几何,思维,水题)

题干&#xff1a; Emuskald needs a fence around his farm, but he is too lazy to build it himself. So he purchased a fence-building robot. He wants the fence to be a regular polygon. The robot builds the fence along a single path, but it can only make fenc…

判断集合相等_数学启蒙的每个关键阶段之集合分类

本文我们将分享数学启蒙学什么&#xff1f;用几个字简单的归纳为集合、数、量、形、时间、空间。我们接下来会讲感知集合和分类&#xff0c;数概念&#xff0c;量的概念&#xff0c;形状包含平面图形和立体图形&#xff0c;空间方位和时间的初步概念。 家长们可以发现幼儿数学启…

【CodeForces - 271B 】Prime Matrix (素数,预处理打表,思维)

题干&#xff1a; Youve got an n  m matrix. The matrix consists of integers. In one move, you can apply a single transformation to the matrix: choose an arbitrary element of the matrix and increase it by 1. Each element can be increased an arbitrary numb…

【CodeForces - 270C】Magical Boxes (思维,进制,有坑)

题干&#xff1a; Emuskald is a well-known illusionist. One of his trademark tricks involves a set of magical boxes. The essence of the trick is in packing the boxes inside other boxes. From the top view each magical box looks like a square with side leng…

虚拟机安装黑群晖_【群晖系统】HEI群辉DSM 6.2.1 系统安装图文教程 (19年2月)

黑群晖系统其实是指在普通电脑运行Synology DSM系统, 事实上在普通PC电脑上安装黑群晖(Synology DSM)也非常方便, 现在把教程简单写一下。引导系统装哪里&#xff1f;非常关键的问题&#xff0c;DSM采用系统和数据相分离的结构&#xff0c;也就是说引导系统需要独立安装在一个设…

【Effect CodeForces - 270D】Greenhouse (思维,最长非递减子序列(上升),对偶问题,考虑反面)

题干&#xff1a; Emuskald is an avid horticulturist and owns the worlds longest greenhouse — it is effectively infinite in length. Over the years Emuskald has cultivated n plants in his greenhouse, of m different plant species numbered from 1 to m. His …

错误1053服务没有及时_无法启动xx服务 错误1053:服务没有及时响应启动或控制请求,排查方法。...

sc安装服务&#xff0c;启动失败&#xff1a;显示错误1053&#xff1a;服务没有及时响应启动或控制请求网上找了很多方法资料&#xff0c;什么注册表啊&#xff0c;权限啊之类的。你按照这些都做完后&#xff0c;仍然提示这个错误。告诉你&#xff0c;要检查自己的程序是不是有…

【CodeForces - 219D 】Choosing Capital for Treeland (树形dp)

题干&#xff1a; The country Treeland consists of n cities, some pairs of them are connected with unidirectional roads. Overall there are n - 1 roads in the country. We know that if we dont take the direction of the roads into consideration, we can get …

数据库分页查询mysql_各种数据库的分页查询SQL语句总结

1.oracle数据库分页select * from (select a.*,rownum rc from 表名 where rownum<endrow) a where a.rc>startrow2.DB2数据库分页Select * from (select rownumber() over() as rc,a.* from (select * from 表名 order by 列名) as a) where rc between startrow and en…

【HihoCoder - 1880】地铁环线 (前缀和,水题,模拟)

题干&#xff1a; H市有一环线地铁&#xff0c;一共包含N站&#xff0c;编号1~N。正向行驶的地铁会按1 -> 2 -> 3 -> ... -> N -> 1的方向行驶&#xff0c;反向会按1 -> N -> N-1 -> ... -> 3 -> 2 -> 1的方向行驶。 给定所有相邻两站之间…

unsigned int mysql_mysql 中int类型字段unsigned和signed的探索

转自&#xff1a;http://www.0791quanquan.com/news_keji/topic_816453/探索一&#xff1a;正负数问题拿tinyint字段来举例&#xff0c;unsigned后&#xff0c;字段的取值范围是0-255&#xff0c;而signed的范围是-128 - 127。 那么如果我们在明确不需要负值存在的情况下&#…