树的直径
直径的性质:距离任意点最远的点一定是直径的一个端点,这个基于贪心求直径方法的正确性可以得出
方法:(d_1,d_2)分别表示距离一个点的最远距离和次远距离,求(d_1+d_2)的最大值
代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn=1e4+10;
int read(){
int x=1,a=0;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') x=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){a=a*10+ch-'0';ch=getchar();}
return x*a;
}
struct node{
int to,next;
}ed[maxn*2];
int tot,head[maxn];
void add(int u,int to){
ed[++tot].to=to;
ed[tot].next=head[u];
head[u]=tot;
}
int d;
int dfs(int x,int fa){
int d1=0,d2=0;
for (int i= head[x];i;i=ed[i].next){
int to=ed[i].to;
if(to==fa) continue;
d=dfs(to,x)+1;
if (d>d1) d2=d1,d1=d;
else if (d>d2) d2=d;
}
d=max(d,d1+d2);
return d1;
}
int n;
int main(){
n=read();
for (int i = 1;i <= n-1;i++){
int x,y;
x=read(),y=read();
add(x,y),add(y,x);
}
dfs(1,-1);
printf("%d
",d);
return 0;
}
树的重心
重心的性质:
以树的重心为根时,所有子树的大小都不超过整棵树大小的一半。
树中所有点到某个点的距离和中,到重心的距离和是最小的;如果有两个重心,那么到它们的距离和一样。
把两棵树通过一条边相连得到一棵新的树,那么新的树的重心在连接原来两棵树的重心的路径上。
在一棵树上添加或删除一个叶子,那么它的重心最多只移动一条边的距离。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
int read(){
int x=1,a=0;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') x=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){a=a*10+ch-'0';ch=getchar();}
return x*a;
}
const int maxn=4e4+10;
struct node{
int to,next;
}ed[maxn*2];
int tot,head[maxn];
void add(int u,int to){
ed[++tot].to=to;
ed[tot].next=head[u];
head[u]=tot;
}
int t,n;
int size[maxn],weight[maxn],tree[2];
void dfs(int x,int fa){
size[x]=1;weight[x]=0;
for (int i = head[x];i;i=ed[i].next){
int to=ed[i].to;
if (to==fa) continue;
dfs(to,x);
size[x]+=size[to];
weight[x]=max(size[to],weight[x]);
}
weight[x]=max(weight[x],n-size[x]);
if (weight[x]<=n/2) tree[tree[0]!=0]=x;
}
int main(){
t=read();
while(t--){
memset(head,0,sizeof(head));
memset(ed,0,sizeof(ed));
memset(size,0,sizeof(size));
memset(weight,0,sizeof(weight));
tree[0]=tree[1]=0;
n=read();
for (int i = 1;i <= n-1;i++){
int x,y;
x=read(),y=read();
add(x,y),add(y,x);
}
dfs(1,-1);
printf("%d %d",tree[0],weight[tree[0]]);
putchar('
');
}
return 0;
}