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)的主要内容,如果未能解决你的问题,请参考以下文章