目录
一.树的直径
(1)定义
(2)思路
(3)例题
(4)std(第一小问)
二.树的重心
(1)介绍
(2)求重心
(3)例题
(4)AC
树的直径是指树中最长的一条路径的长度,这条路径连接树中的两个节点,使得它们之间的距离最远。
P3304 [SDOI2013] 直径 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include
using namespace std;
const int maxn=2e5+5;
int n;
struct Edge{
int u,v,w,next;
}edge[maxn<<1];
int head[maxn],cnt;
void add(int u,int v,int w){
edge[++cnt]=(Edge){u,v,w,head[u]}; head[u]=cnt;
}
int root,lon;
void dfs(int u,int fa,int p){
if(p>lon){
root=u;
lon=p;
}
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].v;
if(v==fa) continue;
dfs(v,u,p+edge[i].w);
}
}
int main(){
scanf("%d",&n);
for(int i=1,u,v,w;i
树的重心是指树中的一个节点,通过删除该节点后,将树分成多个子树,使得每个子树的节点数都不超过整棵树节点数的一半。换句话说,树的重心是树的一种结构特征,它能够将树尽可能平衡地分割成多个相对均匀的部分。
说人话就是重心在树所有节点中,它的最大子树的节点最小
寻找树的重心通常可以通过以下步骤来实现:
#include
#define maxn 10005
using namespace std;
int n;
int size[maxn],f[maxn]; //子树总大小 && 最大子树
struct Edge{
int u,v,next;
}edge[maxn<<1];
int head[maxn],cnt;
void add(int u,int v){
edge[++cnt]=(Edge){u,v,head[u]}; head[u]=cnt;
}
int root,MAX=0x7fffffff;
void dfs(int u,int fa){
size[u]=1;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].v;
if(v!=fa){
dfs(v,u);
size[u]+=size[v];
f[u]=max(f[u],size[v]);
}
}
f[u]=max(f[u],n-size[u]);
if(f[u]
P1395 会议 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include
#define maxn 50005
using namespace std;
int n;
int size[maxn],f[maxn]; //子树总大小 && 最大子树
struct Edge{
int u,v,w,next;
}edge[maxn<<1];
int head[maxn],cnt;
void add(int u,int v,int w){
edge[++cnt]=(Edge){u,v,w,head[u]}; head[u]=cnt;
}
int root,MAX=0x7fffffff;
void dfs(int u,int fa){
size[u]=1;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].v;
if(v!=fa){
dfs(v,u);
size[u]+=size[v];
f[u]=max(f[u],size[v]);
}
}
f[u]=max(f[u],n-size[u]);
if(f[u] q;
q.push((node){root,0});
while(!q.empty()){
node temp=q.top(); q.pop();
int u=temp.u;
if(vis[u]) continue;
vis[u]=1;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].v,w=edge[i].w;
if(dis[u]+w