分析:题目可以简化为给一棵树,从根出发,每个节点都去一次,求走最少边的数目(ans)。
思路:画图分析可知: ans=树的边数*2-树的深度。
注释:
vist数组代表深度,也代表该节点是否在树中。因为有深度和树中存在该节点在代码中是等价的。
lon记录树的深度,lont记录添加的新节点的dis,如果lont>lon 那么树的高度因为该点增加了。
ans:当前树的边的数目的两倍。
#include<iostream>
using namespace std;
int fa[200010],vist[100010];
int n,m,ans;
int lon,lont;
int fnd(int x){
if(vist[x]||fa[x]==-1) {
ans-=2*vist[x];
return vist[x];
}
return vist[x]=fnd(fa[x])+1;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
int x; scanf("%d",&x);
fa[i]=x;
}
while(m--){
int x; scanf("%d",&x);
lont=fnd(x);
ans+=2*lont;
if(lont>=lon) {printf("%d\n",ans-lont); lon=lont;}
else{
printf("%d\n",ans-lon);
}
}
return 0;
}