网站的建设进入哪个科目,wordpress 家庭照片,浙江省特种作业人员证书查询,深圳市文刀网站建设知识#xff1a; 定义#xff1a;重心是指树中的一个结点#xff0c;如果将这个点删除后#xff0c;剩余各个连通块中点数的最大值最小#xff0c;那么这个节点被称为树的重心。 #xff08;最大值的最小值#xff09; 树的重心的性质#xff1a; 1.一个树最多只有1个或… 知识 定义重心是指树中的一个结点如果将这个点删除后剩余各个连通块中点数的最大值最小那么这个节点被称为树的重心。 最大值的最小值 树的重心的性质 1.一个树最多只有1个或2个重心。如果有两个重心它们必定相邻且在树的最长路径中间位置。 2.把两个树通过一条边相连得到一个新的树那么新的树的重心在连接原来两个树的重心的路径上。 3.树中所有点到某个点的距离和中到重心的距离和是最小的 4.把一个树添加或删除一个叶子那么它的重心最多只移动一条边的距离。 会议 - 洛谷
于是乎这个题就可以这样解决
先把树的重心求出来 算出所有其他结点到树的重心的距离之和。 树的重心的求法 dfs遍历每一个点求取每个点作为重心“的最大子树的节点数然后取最小的那个 作为重心。 具体看代码。 代码
#include iostream
#include vector
#include cstring
#include queue
using namespace std;const int N 1e5 10;
int n;
vectorint g[N];
bool vis[N];
int ans 1 30;
int dis[N], res;
queueint q;
int f[N];int dfs(int u) { // 返回值为子树的结点数vis[u] true;int sum 1; // 记录子树int size 0; // 存放子树中节点数最大for(int i 0; i g[u].size(); i ) {int j g[u][i];if(!vis[j]) {int s dfs(j);sum s;size max(size, s); // 比较所有下子树最大节点数}} ans min(ans, max(size, n - sum)); // 和上子树比较求取最大子树结点数f[u] max(size, n - sum); // f[u] 存放u结点最大子树结点数 return sum;
}void bfs(int start) {q.push(start);vis[start] true;while(!q.empty()) {auto t q.front();q.pop();for(int i 0; i g[t].size(); i ) {int j g[t][i];if(!vis[j]) {vis[j] true;dis[j] dis[t] 1;q.push(j);}}}
}int main() {cin n;for(int i 1; i n; i ) {int a, b; cin a b;g[a].push_back(b);g[b].push_back(a);}dfs(1);memset(vis, false, sizeof vis);int st N, start 0;for(int i 1; i n; i ) { //比较每个点最大子树结点数 若有两个重心取编号小的if(st f[i]) {st f[i];start i;}else if(st f[i]) {if(i start) start i;}}bfs(start); //bfs求距离和for(int i 1; i n; i ) {res dis[i];}cout start res endl;return 0;
}