思路:
对于普通DP只能n^2logn,所以加个记忆化
毕竟从一个点走到另一个点它的dp值总是不会变的,所以记录那条边对应那个值就行
满分做法以后或许会补
c o d e 70 分 code 70分 code70分
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int n, a[1001000], dp[1001000];
int head[1001000], tot;
struct node
{
int to, next;
}b[1001000];
void add(int x, int y)
{
b[++tot]=(node){y, head[x]};
head[x]=tot;
b[++tot]=(node){x, head[y]};
head[y]=tot;
}
int dfs(int x, int fa, int f)
{
if(f && dp[f])
return dp[f];
priority_queue<int> q;
for(int i=head[x]; i; i=b[i].next)
{
int y=b[i].to;
if(y==fa)
continue;
q.push(dfs(y, x, i));
}
int res=0;
for(int i=1; !q.empty(); i++, q.pop())
res=max(res, q.top()+i);
dp[f]=res;
return res;
}
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(i, x);
}
int ans=1e9;
for(int i=1; i<=n; i++)
{
a[i]=dfs(i, 0, 0);
if(a[i]<ans)
ans=a[i];
}
printf("%d\n", ans+1);
for(int i=1; i<=n; i++)
if(ans==a[i])
printf("%d ", i);
return 0;
}