动态规划特训:Hali-Bula的晚会(UVA1220)

博客围绕典型的树形dp中最大独立集问题展开。以公司员工聚会,要求员工和其直接上司不同时到场为例,定义数组求解最多到场人数及方案是否唯一,还给出了示例输入输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解题思路:此题是典型的树形dp中最大独立集的问题。定义两个数组s[u]和gs[u],分别代表选择u时只能选孙节点gs[u]和不选择u时选择其儿子的最大值。这里使用刷表的方法,随时更新s[u]和gs[u]两个数组。因为需要判断是否唯一,因而定义了三个数组,分别对应选子节点和孙节点是否唯一以及判断子节点和孙节点大小并选择后最终的本节点是否唯一。

题目大意:一个公司员工要举行聚会,要求任意一个人不能和他的直接上司同时到场,一个员工只有一个支系上司,现在求最多有多少人到场,并且方案是否唯一。

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

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<string>
#include<vector>
using namespace std;


int n,s[201],gs[201],sf[201],gf[201],f[201];
map<string,int> Q1;
map<int,string> Q2;
vector<int> Q[201];

int dfs(int u,int fa)
{
	if(Q[u].empty()) return 1;
	for(int i=0;i<Q[u].size();i++)
	{
		if(Q[u][i]!=fa)   //父节点对应的不是子树 
		{
			s[u]+=dfs(Q[u][i],u);
			if(f[Q[u][i]]==1) sf[u]=1;  //若有子节点不唯一,则待选择的子节点最大不唯一 
		}
		if(fa!=-1)    
		{
			gs[fa]+=dfs(Q[u][i],u);
			if(f[Q[u][i]]==1) gf[fa]=1;  //有孙节点不唯一,则对应的节点待选择孙节点最大不唯一 
		}
	}
	if(s[u]==gs[u]+1) {   //孙与子节点最大相等,则本节点不唯一 
		f[u]=1;
		return s[u];
	}
	int ans;
	if(s[u]>gs[u])   //选择子节点 
	{
		f[u]=sf[u];   
		ans=s[u];
	}
	else     //选择孙节点 
	{
		f[u]=gf[u];
		ans=gs[u];
	}
	return ans;
}

int main()
{
	while(cin>>n)
	{
		if(n==0) break;
		int count=2;
		Q1.clear();Q2.clear();
		for(int i=1;i<=n;i++) Q[i].clear(); 
		memset(s,0,sizeof(s));memset(gs,0,sizeof(gs));
		memset(sf,0,sizeof(sf));memset(gf,0,sizeof(gf));
		memset(f,0,sizeof(f));
		string s;cin>>s;Q1[s]=1;Q2[1]=s;
		for(int i=2;i<=n;i++)
		{
			string s1,s2;
			cin>>s1>>s2;
			if(Q1.count(s1)==0) {
				Q1[s1]=count;
				Q2[count++]=s1;
			}
			Q[Q1[s2]].push_back(count-1);
		}
		cout<<dfs(1,-1)<<" ";
		if(f[1]==1) cout<<"NO"<<endl;
		else cout<<"YES"<<endl;
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值