树的重心
#include
#include
#include
#include
using namespace std;
const int N=50010;//常量
struct use{
int st,en;//st为起点,en 为终点
}b[1000001];//存储边信息
int son[N],n,ans[N],minn,next[5000001]={0},point[100001]={0},tot;
//son记录最大子节点树,下标表示结点的值
bool f[N];
//通讯图的构建:创建边的起点和终点
void add(int x,int y){
tot++; //记录边的编号
next[tot]=point[x]; //表示与当前tot边同一起点x的上一条边的编号
point[x]=tot; //point存储当前点的最后一条连接边
b[tot].st=x; //边的起点是x
b[tot].en=y; //边的终点是y
return;
}
//深搜:查找以结点x为起点的所有结点的子树结点数
void dfs(int x){//x为结点值
int u,balance=0;
son[x]=0;
f[x]=false; //标记为false的点,避免双向边重复记录结点数
for(int i=point[x];i;i=next[i]){
u=b[i].en; //边的终点
if(!f[u]) //点u被标记为false
continue; //跳过本层循环,继续查找下一个子节点
dfs(u); //找到新的根节点,继续深搜
son[x]+=son[u]+1; //子节点数=儿子的子节点数+1(本身)
//balance表示以结点i为父亲的子树中,结点个数的最大值
balance=max(balance,son[u]+1);
}
//还有一棵由原根节点为根的树,它的节点数就是原树总结点数-(被取点的儿子树+1)
balance=max(balance,n-son[x]-1);
//ans存放重心结点编号,ans[0]记录重心的个数
if(balance>n;
minn=1000001;
memset(f,1,sizeof(f)); //初始化函数,将f中的内容全部设置为1
for(int i=1;i>x>>y;
//添加双向边
add(x,y);
add(y,x);
}
//从任意一个点开始深搜,进行每个结点的子树结点数【balance】统计
dfs(1);
sort(ans+1,ans+ans[0]+1);
for(int i=1;i<=ans[0];i++)
cout<
树的直径
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn=100001;
//创建边结构体--有两个端点属性
struct node{
int to,next;//next 存从起点出发的上一条边的下标 to到那个结点
}edge[maxn];
int cnt=1; //记录边的编号
int vis[maxn],head[maxn],dis[maxn];
//添加边--传入边的起点和终点
void add(int u,int v){
cnt++; //记录边的编号
edge[cnt].to=v; //记录边指向点V
edge[cnt].next=head[u]; //***记录边的上一条边
head[u]=cnt; //存储以u出发的新加入的边的编号
}
void dfs(int x){
vis[x]=1; //当前结点参与了深搜过程,则被标记
//循环执行以x为起点的所有条边-->从最后加入的边开始,到最先加入的边结束
for(int i=head[x];i;i=edge[i].next){
if(!vis[edge[i].to]){ //如果这条边的终点未被记录过,则计数并继续深搜
dis[edge[i].to]=dis[x]+1; //当前点的边权加一
dfs(edge[i].to); //继续深搜
}
}
}
int main(){
//输入点的数量
int n;
cin>>n;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
//创建边
for(int i=1;i>u>>v;
add(u,v);
add(v,u);
}
dis[1]=1;
//第一次深搜
dfs(1);
int pos=1;
//找到树直径的一个端点
for(int i=1;i<=n;i++){
if(dis[i]>dis[pos])
pos=i;
}
memset(vis,0,sizeof(vis));
dis[pos]=1;
//第二次深搜
dfs(pos);
//找到另一个端点 ,以及两个端点之间的最远距离
int ans=0;
for(int i=1;i<=n;i++){
if(dis[i]>ans)
ans=dis[i];
}
cout<