【图论】树的直径

树的直径即为一棵树中距离最远的两点之间的路径

方法一:DFS

先以任意一点为起点跑一遍dfs,记录离起点距离最远的点p(这个点一定是直径的一个端点,感性理解一下不证明了),然后再以最远点再跑一遍dfs,记录此时距离最远的点q,那么pq就是该树的直接

树中有负权边时不可以用这个方法

cpp 复制代码
const int N = 10000 + 10;

int n, c, d[N];
vector<int> g[N];

void dfs(int u, int fa)
{
    for (int v : E[u])
    {
        if (v == fa) continue;
        d[v] = d[u] + 1; // 如边有权值,把1换成权值即可
        if (d[v] > d[c]) c = v; // 更新最大距离的点
        dfs(v, u);
    }
}

int main()
{
    cin >> n;
    for (int i = 1; i < n; i++)
    {
        int u, v;
        scanf("%d %d", &u, &v);
        g[u].push_back(v), g[v].push_back(u);
    }
    dfs(1, 0); // 第一遍dfs
    int p = c; // 一个端点
    d[c] = 0;
    dfs(c, 0); // 第二遍dfs
    int q = c; // 另一个端点
    cout << d[c];
    return 0;
}

方法二:树形dp

dp[u]为以u为根的子树中离u最远的点的路径长度

转移方程(v为u的子结点):dp[u] = max(dp[u], dp[v] + w(u, v))

两条经过根结点的最长路径即为该子树中的直径

转移方程:zj = max(zj, dp[u] + dp[v] + w(u, v))

cpp 复制代码
const int N = 10000 + 10;

int n, zj = 0;
int dp[N];
vector<int> g[N];

void dfs(int u, int fa)
{
    for (int v : E[u])
    {
        if (v == fa) continue;
        dfs(v, u);
        zj = max(zj, dp[u] + dp[v] + 1); // 如为有权边,把1换成权值即可
        dp[u] = max(dp[u], dp[v] + 1); // 如为有权边,把1换成权值即可
    }
}

int main()
{
    cin >> n;
    for (int i = 1; i < n; i++)
    {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v), g[v].push_back(u);
    }
    dfs(1, 0);
    cout << zj << '\n';
    return 0;
}
相关推荐
啊董dong6 分钟前
noi-2025年12月16号作业
数据结构·c++·算法·noi
white-persist9 分钟前
【攻防世界】reverse | simple-check-100 详细题解 WP
c语言·开发语言·汇编·数据结构·c++·python·算法
长安er17 分钟前
LeetCode 01 背包 & 完全背包 题型总结
数据结构·算法·leetcode·动态规划·背包问题
小南家的青蛙21 分钟前
LeetCode第2658题 - 网格图中鱼的最大数目
算法·leetcode·职场和发展
ZHang......35 分钟前
LeetCode 1114. 按序打印
java·开发语言·算法
仰泳的熊猫1 小时前
1083 List Grades
数据结构·c++·算法·pat考试
Tan_Zhixia1 小时前
时间复杂度判断
数据结构·c++·算法
雪弯了眉梢1 小时前
OpenGL(八)摄像机(Camera)
算法·图形渲染·opengl
~~李木子~~1 小时前
基于 MovieLens-100K 数据集的推荐算法设计与实现
算法·机器学习·推荐算法
Abona1 小时前
智驾空间智能、物理智能、世界模型相关的最新论文和开源算法链接
算法