天梯赛L2-043 龙龙送外卖
思路:可以得到要求的结果是最小生成树*2-当前最深节点的深度
用bfs dep[i]维护节点的深度,对于最小生成树我们可以想到记录此节点到根节点的路径d[i],
dfs从当前节点走到根节点ans依次+2且用st标记走过的路径(因为是最小生成树所以每条路径走一遍)
#include<bits/stdc++.h>
#define pb push_back
#define pp poop_back
#define se second
#define fi first
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N=500010,mod=1e9+7;
bool st[N];
int e[N],ne[N],h[N],idx;//存储儿子结点
int heigth[N];//存储父节点
int d[N];
int root,ans=0;
void add(int a,int b)
{
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
void BFS()
{
queue<int> q;
q.push(root);
st[root]=1;
while(q.size())
{
int t=q.front();
q.pop();
for(int i=h[t];~i;i=ne[i])
{
int j=e[i];
if(!st[j])
{
heigth[j]=heigth[t]+1;
q.push(j);
st[j]=1;
}
}
}
}
void dfs(int x)
{
if(st[x]||x==root) return ;
ans+=2;
st[x]=1;
dfs(d[x]);
}
int main()
{
memset(h,-1,sizeof h);
int n;cin>>n;
int m;cin>>m;
for(int i=1;i<=n;i++)
{
int x;cin>>x;
d[i]=x;
if(x==-1) root=i;
else
{
add(x,i);
add(i,x);
}
}
BFS();
memset(st,0,sizeof st);
int maxh=0;
for(int i=0;i<m;i++)
{
int x;
cin>>x;
maxh=max(heigth[x],maxh);
dfs(x);
// cout<<"***"<<ans<<endl;
cout<<ans-maxh<<endl;
}
return 0;
}