关于树的直径的一切

观前须知

本文使用 CC BY-NC-SA 4.0 许可
本文所有详细证明可见 OI Wiki

笔者的博客主页

正文

定义

树的直径指树上任意两点间距离的最大值

两次DFS

先以任意点为根找到最远点 \(v\)
再以 \(v\) 为根找到最远点 \(u\)
\(u-v\) 即为该树的一条直径

适用范围:无负权树
证明:
\(v\) 为直径的一个端点时显然成立
反证法假设存在更长路径
分类讨论+画图可得矛盾

代码:

int dis[AwA], ans;

void Dfs(int u, int fa) {
    if (dis[u] > dis[ans]) ans = u;
    for (int i = head[u]; i; i = e[i].nxt) {
        int v = e[i].v;
        if (v == fa) continue;
        dis[v] = dis[u] + e[i].w;
        Dfs(v, u);
    }
}

int GetAns() {
    dis[1] = ans = 0;
    Dfs(1, 0);
    dis[ans] = 0;
    Dfs(ans, 0);
    return dis[ans];
}

树型DP

Dfs,以当前点为中间点,考虑最长链和次长链,并把最长链继续上传

代码:

int f[AwA], ans;

void Dfs(int u, int fa) {
    for (int i = head[u]; i; i = e[i].nxt) {
        int v = e[i].v;
        if (v == fa) continue;
        Dfs(v, u);
        ans = max(ans, f[u] + f[v] + e[i].w);
        f[u] = max(f[u], f[v] + e[i].w);
    }
}

性质

树的权非负时,树的直径中点重合
反证法易证

热门相关:恶魔总裁霸道宠:老婆,甜似火   绝宠小医妃:王爷,来一针   嫁入豪门后我养崽盘大佬   世界第一校长   赠我深爱如长风