admin管理员组文章数量:1026989
树的重心总结
树的重心
一、定义
树的某个节点,当去掉该节点后,树的各个连通分量中,节点数最多的连通分量其节点数达到最小值;
二、性质
- 以树的重心为根时,所有子树的大小都不超过整棵树大小的一半。
- 树中所有点到某个点的距离和中,到重心的距离和是最小的;如果有两个重心,那么到它们的距离和一样。
- 把两棵树通过一条边相连得到一棵新的树,那么新的树的重心在连接原来两棵树的重心的路径上。
- 在一棵树上添加或删除一个叶子,那么它的重心最多只移动一条边的距离。
三、求法
用搜索,搜索出以每个结点为根节点的子树上的节点个数,为子联通分量,则其的父连通分量为总个数减去子联通分量,再找到最小值即可;
四、代码
#include <cstdio>
#include <vector>
#include <algorithm>
#define MAXN 105
using namespace std;
int n, dp[MAXN], dp1[MAXN], ans = 2147483647, ans1[MAXN], len, sum;
bool flag[MAXN];
vector < int > g[MAXN];
void dfs(int i) {dp[i] = 1;flag[i] = true;for (int t = 0; t < g[i].size(); t++) {int v = g[i][t];if (!flag[v]) {dfs(v);dp1[i] = max(dp1[i], dp[v]);dp[i] += dp[v];}}dp1[i] = max(dp1[i], n - dp[i]);return;
}
int main() {scanf("%d", &n);for (int i = 1; i < n; i++) {int x, y;scanf("%d %d", &x, &y);g[x].push_back(y);g[y].push_back(x);}dfs(1);for (int i = 1; i <= n; i++) {if (dp1[i] < ans) {ans = dp1[i];len = 1;ans1[len] = i;} else if (dp1[i] == ans) {ans1[++len] = i;}}printf("%d\n", len);for (int i = 1; i <= len; i++) {printf("%d\n", ans1[i]);}return 0;
}
树的重心总结
树的重心
一、定义
树的某个节点,当去掉该节点后,树的各个连通分量中,节点数最多的连通分量其节点数达到最小值;
二、性质
- 以树的重心为根时,所有子树的大小都不超过整棵树大小的一半。
- 树中所有点到某个点的距离和中,到重心的距离和是最小的;如果有两个重心,那么到它们的距离和一样。
- 把两棵树通过一条边相连得到一棵新的树,那么新的树的重心在连接原来两棵树的重心的路径上。
- 在一棵树上添加或删除一个叶子,那么它的重心最多只移动一条边的距离。
三、求法
用搜索,搜索出以每个结点为根节点的子树上的节点个数,为子联通分量,则其的父连通分量为总个数减去子联通分量,再找到最小值即可;
四、代码
#include <cstdio>
#include <vector>
#include <algorithm>
#define MAXN 105
using namespace std;
int n, dp[MAXN], dp1[MAXN], ans = 2147483647, ans1[MAXN], len, sum;
bool flag[MAXN];
vector < int > g[MAXN];
void dfs(int i) {dp[i] = 1;flag[i] = true;for (int t = 0; t < g[i].size(); t++) {int v = g[i][t];if (!flag[v]) {dfs(v);dp1[i] = max(dp1[i], dp[v]);dp[i] += dp[v];}}dp1[i] = max(dp1[i], n - dp[i]);return;
}
int main() {scanf("%d", &n);for (int i = 1; i < n; i++) {int x, y;scanf("%d %d", &x, &y);g[x].push_back(y);g[y].push_back(x);}dfs(1);for (int i = 1; i <= n; i++) {if (dp1[i] < ans) {ans = dp1[i];len = 1;ans1[len] = i;} else if (dp1[i] == ans) {ans1[++len] = i;}}printf("%d\n", len);for (int i = 1; i <= len; i++) {printf("%d\n", ans1[i]);}return 0;
}
本文标签: 树的重心总结
版权声明:本文标题:树的重心总结 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/IT/1694664633a254770.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论