2021.7.13提高B组模拟2T1 消息传递(记忆化搜索)(70分)(P2018 AC)

Posted SSL_LKJ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021.7.13提高B组模拟2T1 消息传递(记忆化搜索)(70分)(P2018 AC)相关的知识,希望对你有一定的参考价值。

消息传递

题目传送门

题目大意

每个人只有一个上司

你可以将一件消息告诉其中一个人(告诉他也有1个单位时间),那个人每个单位时间只能告诉自己的上司或一个员工

最后一个人知道的时间最早是多少,可以从哪些人开始(从小到大)

输入样例

8
1
1
3
4
4
4
3

输出样例

5
3 4 5 6 7

解题思路

枚举每个节点为起点

从它最大的子节点往下找

记得记忆化搜索

注意:
洛谷P2018 可 AC
gmoj 只有70

代码

#include<iostream>
#include<cstring>//gmoj必要用
#include<cstdio>
#include<queue>
using namespace std;
int n,tot,mmin=0x3f3f3f3f,b[2000005],f[4000005],head[2000005];
struct node
{
	int to,next;
}a[4000005];
void add(int x,int y)
{
	a[++tot]=(node){y,head[x]};
	head[x]=tot;
}
int dfs(int x,int fa,int bian)
{
	if(bian&&f[bian])return f[bian];//记忆化
	priority_queue<int> q;//堆
	for(int i=head[x];i;i=a[i].next)//枚举每条边
	{
		int y=a[i].to;
	 	if(y!=fa)
		 q.push(dfs(y,x,i));
	}
	int ans=0;
	for(int i=1;!q.empty();i++,q.pop())
	 ans=max(ans,q.top()+i);
	return f[bian]=ans;
}
int main()
{
	freopen("news.in","r",stdin);
	freopen("news.out","w",stdout);
	scanf("%d",&n);
	for(int i=2;i<=n;i++)
	{
		int x;
		scanf("%d",&x);
		add(x,i);add(i,x);//建边
	}
	for(int i=1;i<=n;i++)
	{
		b[i]=dfs(i,0,0)+1;//记忆化
		mmin=min(mmin,b[i]);
	}
	printf("%d\\n",mmin);
	for(int i=1;i<=n;i++)
	 if(b[i]==mmin)printf("%d ",i);
	return 0;
}

谢谢

以上是关于2021.7.13提高B组模拟2T1 消息传递(记忆化搜索)(70分)(P2018 AC)的主要内容,如果未能解决你的问题,请参考以下文章

2021.8.10提高B组模拟2T1 单峰(快速幂)

2021.7.13提高B组模拟2T2 JIH的玩偶(倍增)

2017.12.09NOIP提高组模拟赛A组

2017.07.16【NOIP提高组】模拟赛B组 卫星照片 题解

2017.07.14NOIP提高组模拟赛B组

2021.7.21提高B组模拟8T1 好数(模拟)