题目链接:https://codeforces.com/problemset/problem/686/D
题解:
给了一颗树,n个点,n-1条边,1为根节点。 m次查询,查询子树重心。
重心的定义:在树上找一个点,这个点所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心。
重心的一些性质:
1.删除重心节点之后,一颗树会分成一些连通块,其中最大的连通块的结点个数应该小于等于总结点数的一半。
2.树中所有点到某个点的距离和中,到重心的距离和是最小的;如果有两个重心,那么他们的距离和一样。
这道题是一个有根数,以x为结点的子树的重心必定在x的子树节点个数最多的那个子树中,而且重心不会下降。那么可以进行dfs,回溯的时候自底向上进行计算每棵树的重心。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+5;
int n,m;
int ans[maxn];
int siz[maxn];
int maxx[maxn];
int fa[maxn];
int head[maxn],nex[maxn],to[maxn],cnt;
void add(int i,int j){
cnt++;
to[cnt]=j;nex[cnt]=head[i];head[i]=cnt;
}
void dfs(int x){
siz[x]=1;
int p=x;