首先我们把无根树变成有根树
一个点的受损次数来自于:
1.父亲的父亲结点的贡献
2.父亲结点的贡献
3.兄弟结点的贡献
4.孩子结点的贡献
具体看代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=750000+100;
vector<int>G[maxn];
int fa[maxn];//父亲结点
int ans[maxn];//孩子结点对父亲结点和父亲的父亲结点的贡献
int a[maxn];//父亲结点和父亲的父亲结点对孩子结点的贡献
int res[maxn];//兄弟结点对兄弟结点的贡献,所以只要更新res[fa[x]],x的兄弟结点(包括自己)都可以得到贡献
void dfs(int u,int f){
fa[u]=f;
int len=G[u].size();
for(int i=0;i<len;i++){
int v=G[u][i];
if(v==f) continue;
dfs(v,u);
}
}
int main(){
int n,q;
scanf("%d%d",&n,&q);
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1,0);
while(q--){
int node;
scanf("%d",&node);
a[node]++;
ans[fa[node]]++;ans[fa[fa[node]]]++;
res[fa[node]]++;
printf("%d\n",ans[node]+a[fa[node]]+a[fa[fa[node]]]+res[fa[node]]); //孩子结点的贡献+父亲结点的贡献+父亲的父亲结点的贡献+兄弟结点的贡献
}
}