树的直径及其性质

参考:​​树的直径及其性质与证明​​

①直径两端点一定是两个叶子节点

②距离任意点最远的点一定是直径的一个端点,这个基于贪心求直径方法的正确性可以得出

③如果第一棵树直径两端点为\((u,v)\),第二棵树直径两端点为\((x,y)\),用一条边将两棵树连接,那么新树的直径一定是\(u,v,x,y\)中的两个点

④对于一棵树,如果在一个点的上接一个叶子节点,那么最多会改变直径的一个端点

⑤若一棵树存在多条直径,那么这些直径交于一点且交点是这些直径的中点

// Created by CAD on 2020/4/9.
#include <bits/stdc++.h>

#define mst(name, value) memset(name,value,sizeof(name))
using namespace std;

const int maxn=5e4+5;
vector<int> g[maxn];
int a[maxn],dx[maxn],dy[maxn];
int dfs(int x,int f,int *d){
int ans=x;
for(auto i:g[x]){
if(i==f) continue;
d[i]=d[x]+1;
int now=dfs(i,x,d);
if(d[now]>d[ans]) ans=now;
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;cin>>n;
for(int i=1;i<=n;++i) cin>>a[i];
for(int i=1;i<=n-1;++i){
int u,v;cin>>u>>v;
g[u].push_back(v),g[v].push_back(u);
}
int x=dfs(1,0,dx); //随机找一个点,找到距离它最远的一个点,即为直径的一个端点
mst(dx,0);
int y=dfs(x,0,dx); //从x出发,找到距离x最远的一个点,为直径的另一个端点,dx表示点到x的距离
dfs(y,0,dy); //求得dy

return 0;
}

CAD加油!欢迎跟我一起讨论学习算法,