当前位置 博文首页 > 油炸皮卡丘yue的博客:树的直径(求法以及练习)

    油炸皮卡丘yue的博客:树的直径(求法以及练习)

    作者:[db:作者] 时间:2021-09-21 21:05

    何为树的直径,
    简单来说其实就是在一棵树上, 距离最远的两个点的距离.
    如何求直径

    1. b f s ( d f s ) bfs(dfs) bfs(dfs):第一次 b f s ( d f s ) bfs(dfs) bfs(dfs) :从任意节点出发, 求出到该节点最远的节点 p p p, 然后进行第二次 b f s ( d f s ) bfs(dfs) bfs(dfs), 求出到 p p p最远的节点 q q q, p p p q q q的路径长度即为树的直径.
    2. 树形 d p dp dp: 设 d p [ x ] dp[x] dp[x]表示从节点 x x x出发走向以 x x x为根的子树,能够到达的最远节点的距离, 设集合 y 1 , y 2 , y 3 , . . . . . . y t {y1, y2, y3,......yt} y1,y2,y3,......yt x x x的子节点, e d g e ( x , y ) edge(x,y) edge(x,y)为边的权值大小, 则状态转移方程为 d p [ x ] = max ? 1 < = i < = t d p [ y i ] + e d g e ( x , y i ) dp[x]=\displaystyle\max_{1<=i<=t}{dp[y_i] + edge(x,y_i)} dp[x]=1<=i<=tmax?dp[yi?]+edge(x,yi?), 接下来我们考虑对于每个节点 x x x求出经过 x x x的最长链的长度 l e n [ x ] len[x] len[x], max ? 1 < = i < = n l e n [ i ] \displaystyle\max_{1<=i<=n}len[i] 1<=i<=nmax?len[i]即位树的直径长度

    练习
    巡逻
    本题需要求两次树的直径, 第一次求完直径之后需要将直径上的边的权值变为 ? 1 -1 ?1.哦, 还有重要的一点, 在负权树上, 不能用 b f s ( d f s ) bfs(dfs) bfs(dfs)求直径, 只能用 d p dp dp求.
    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> P;
    #define x first
    #define y second
    const int MAX_N = 2e5 + 5;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-6;
    //
    //
    int n, k, tot;
    int p, q, l1, l2, maxlen;
    int d[MAX_N], pre[MAX_N];
    int head[MAX_N];
    bool vis[MAX_N], used[MAX_N];
    struct node { int to, cost, next;} G[MAX_N];
    inline void add(int u, int v, int w) {
        ++ tot;
        G[tot] = node{v, w, head[u]};
        head[u] = tot;
    }
    void dfs1(int x, int fa) {
        for(int i = head[x]; ~i; i = G[i].next) {
            int y = G[i].to, z = G[i].cost;
            if(y == fa) continue;
            d[y] = d[x] + z;
            dfs1(y, x);
        }
    }
    void dfs2(int x, int fa) {
        for(int i = head[x]; ~i; i = G[i].next) {
            int y = G[i].to, z = G[i].cost;
            if(y == fa) continue;
            d[y] = d[x] + z;
            pre[y] = x;
            dfs2(y, x);
        }
    }
    void dfs_tree_maxlen()
    
    下一篇:没有了