两次DFS法
宏定义
- #define T_D_T int:树边权的类型。
变量
- int s:直径一端点。
- int t:直径另一端点。
- T_D_T d[i]:节点 i 到搜索起点的距离。
- T_D_T len:直径长度。
函数
- void init():初始化。
- void dfs(int x,int fa):计算子树 x 中的 d 值,并更新直径的端点 s,x 的父亲为 fa。
- 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:树边权的类型。
变量
- T_D_T d1[i]:从节点 i 出发的最长路的长度。
- T_D_T d2[i]:从节点 i 出发的次长路的长度。
- T_D_T len:直径长度。
函数
- void init():初始化。
- void dfs(int x,int fa):计算子树 x 中的 d1,d2 值,并更新答案 len,x 的父亲为 fa。
- 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;