【算法-树论】树的直径

定义

树上任意两节点之间最长的简单路径即为树的直径。


寻找方法:两遍 dfs 或树形 DP。

dfs 方法:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int man = 1e4+10;
class Graph_D {
public:
    int hed[man], len = 1;
    int nxt[man<<1], ver[man<<1];
    void Ins (int u, int v) {
        ver[++len] = v;
        nxt[len] = hed[u];
        hed[u] = len;
        return ;
    } 
    void DIns (int u, int v) {
        Ins(u, v), Ins(v, u);
        return ;
    }
} G;

int n, k, l, r, mal;
bool vis[man];
void dfs (int x, int len) {
    vis[x] = 1;
    if (mal < len) mal = len, r = x;    
    for (int i = G.hed[x]; i; i = G.nxt[i]) {
        int v = G.ver[i];
        if (!vis[v]) dfs(v, len+1);
    } vis[x] = 0;
    return ;
} 
int main () {
#ifndef ONLINE_JUDGE
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif
    scanf("%d", &n);
    for (int u, v, i = 1; i < n; ++ i) scanf("%d%d", &u, &v), G.DIns(v, u);
    dfs(1, 0);
    l = r, mal = 0;
    dfs(l, mal);
    printf("%d", mal);
    return 0;
}

例题

(若要记录直径节点,则在第二次深搜时记录前端节点。)

树形 DP 方法:

记录每个节点的最长路径 \(dep1\) 和次长路径 \(dep2\)

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int man = 1e4+10;
class Graph_D {                                                                                                                                                                                                               
public:
    int hed[man], len = 1;
    int nxt[man<<1], ver[man<<1];
    void Ins (int u, int v) {
        ver[++len] = v;
        nxt[len] = hed[u];
        hed[u] = len;
        return ;
    } 
    void DIns (int u, int v) {
        Ins(u, v), Ins(v, u);
        return ;
    }
} G;

int n, res;
int dep1[man] = {-1}, dep2[man] ={-1};
void dfs (int x, int fa) {
    dep1[x] = dep2[x] = 0;
    for (int i = G.hed[x]; i; i = G.nxt[i]) {
        int v = G.ver[i];
        if (v == fa) continue;
        dfs(v, x);
        int d = dep1[v]+1;
        if (d > dep1[x]) dep2[x] = dep1[x], dep1[x] = d;
        else if (d > dep2[x]) dep2[x] = d;
    } res = max(res, dep1[x]+dep2[x]);
    return ;
} 
signed main (void) {
#ifndef ONLINE_JUDGE
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif
    scanf("%d", &n);
    for (int u, v, i = 1; i < n; ++ i) scanf("%d%d", &u, &v), G.DIns(v, u);
    dfs(1, 0);
    printf("%d", res);
    return 0;
}
posted @ 2023-05-23 20:05  STA_Morlin  阅读(24)  评论(0)    收藏  举报