分析:
这题是一道很好的DFS题,首先我们要找规律,发现这个最短路径其实是我们所走路程两倍再减去到根节点最长的那条边,因此我们DFS的过程中一直维护一个所走的路径的长度以及最长的点到根节点的距离,就可以把这题给做出来了。
补充一下这题的讲解地址,在AcWing,里面有视频讲解,不懂可以去看一下
https://www.acwing.com/problem/content/4477/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
int dis[maxn], p[maxn];//dis是该点到根节点的距离, p是该点的父节点
int sum; //记得是当前情况下所需要走过的单程路程,不包括回程
int maxx,n,m;//maxx记录的是离根结点最远的那个点的距离
int dfs(int u){
if(p[u]==-1||dis[u]>0) return dis[u];
sum++;
dis[u]=dfs(p[u])+1;
return dis[u];
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++) scanf("%d",&p[i]);
while(m--){
int x;
scanf("%d",&x);
maxx=max(maxx,dfs(x));
printf("%d\n",sum*2-maxx);
}
return 0;
}