dfklsJj

3.2通过求维护lca的最长链和次长链来求树的直径

inline void work(){
	dfs(1,0);//0号节点是虚点,编号要从1开始编
	int x=1;
	for(int i=2;i<=n;++i) 
		if(deep[i]>deep[x])
			x=i;
	dfs(x,0);
	int y=1;
	for(int i=2;i<=n;++i)
		if(deep[i]>deep[y])
			y=i;
	printf("%d %d",x,y);//直径的俩端点
	printf("%d",deep[y]);//直径
}

3.2通过求维护lca的最长链和次长链来求树的直径

/*****************************************************************/
int n,ans=INT_MAX;
int siz[N];//记录i节点的子树大小
int son[N];//记录i节点的重儿子

inline void dfs(int u,int fa){
	siz[u]=1;
	for(int i=head[u];i;i=e[i].next){//遍历整棵树
		int v=e[i].v;//取出后继节点v
		if(v==fa)continue;//如果后继节点是来时的父亲节点,跳过搜索
		dfs(v,u);//继续以v为当前节点,u为父亲节点深度优先搜索
		siz[u]+=siz[v];//搜索完毕后,用子节点的子树大小来更新父节点子树大小
		if(siz[v]>siz[son[u]])
			son[u]=v;
	}
	int max_size=max(siz[son[u]],n-siz[u]);
	ans=min(ans,max_size);//求重心具体是谁:如果ans被更新了就记录一下u
}

int main(){
	scanf("%d",&n); 
	for(int i=1;i<=n-1;++i){
	    int u,v;
		scanf("%d %d",&u,&v);
	    add_edge(v,u),add_edge(u,v);
	}
	dfs(1,0);
	printf("%d",ans);
    return 0;
}

/*************************************************************/
inline void find_first_branch(){
	dfs2(x,0);
}
posted @ 2020-02-24 14:06  设计涉及社稷  阅读(94)  评论(0编辑  收藏  举报