树的直径

两次DFS法

宏定义

  • #define T_D_T int\texttt{\#define T\_D\_T int}:树边权的类型。

变量

  • int s\texttt{int s}:直径一端点。
  • int t\texttt{int t}:直径另一端点。
  • T_D_T d[i]\texttt{T\_D\_T d[i]}:节点 ii 到搜索起点的距离。
  • T_D_T len\texttt{T\_D\_T len}:直径长度。

函数

  • void init()\texttt{void init()}:初始化。
  • void dfs(int x,int fa)\texttt{void dfs(int x,int fa)}:计算子树 xx 中的 dd 值,并更新直径的端点 ssxx 的父亲为 fafa
  • void calc()\texttt{void calc()}:计算树的直径。

代码

#define T_D_T int
struct Tree_Diameter{
	int s,t;
	T_D_T d[N],len;
	void init(){
		s=t=0;
		len=0;
		memset(d,0,sizeof(d));
	}
	void dfs(int x,int fa){
		for(int i=head[x];i;i=nxt[i]){
			int y=ver[i];
			T_D_T z=edge[i];
			if(y==fa)
				continue;
			d[y]=d[x]+z;
			if(d[y]>d[s])
				s=y;
			dfs(y,x);
		}
	}
	void calc(){
		init();
		dfs(1,0);
		d[t=s]=0;
		dfs(s,0);
		len=d[s];
	}
}tree;

树形DP法

宏定义

  • #define T_D_T int\texttt{\#define T\_D\_T int}:树边权的类型。

变量

  • T_D_T d1[i]\texttt{T\_D\_T d1[i]}:从节点 ii 出发的最长路的长度。
  • T_D_T d2[i]\texttt{T\_D\_T d2[i]}:从节点 ii 出发的次长路的长度。
  • T_D_T len\texttt{T\_D\_T len}:直径长度。

函数

  • void init()\texttt{void init()}:初始化。
  • void dfs(int x,int fa)\texttt{void dfs(int x,int fa)}:计算子树 xx 中的 d1,d2d1,d2 值,并更新答案 lenlenxx 的父亲为 fafa
  • void calc()\texttt{void calc()}:计算树的直径。

代码

#define T_D_T int
struct Tree_Diameter{
	T_D_T d1[N],d2[N],len;
	void init(){
		len=0;
		memset(d1,0,sizeof(d1));
		memset(d2,0,sizeof(d2));
	}
	void dfs(int x,int fa){
		d1[x]=d2[x]=0;
		for(int i=head[x];i;i=nxt[i]){
			int y=ver[i];
			T_D_T z=edge[i];
			if(y==fa)
				continue;
			dfs(y,x);
			int t=d1[y]+z;
			if(t>d1[x]){
				d2[x]=d1[x];
				d1[x]=t;
			}
			else if(t>d2[x])
				d2[x]=t;
		}
		len=max(len,d1[x]+d2[x]);
	}
	void calc(){
		init();
		dfs(1,0);
	}
}tree;
posted @ 2022-08-30 20:19  luckydrawbox  阅读(13)  评论(0)    收藏  举报  来源