欢迎来踩本人博客
树的直径:
就是树上最长路
方法 :
求两边DFS即可

步骤:
1.从任意一点进行dfs,然后找到一个最长路径,记录最远点u
2.然后从u再进行dfs,找最长路径,记录一点v。
(u,v)就是树的直径

证明:可以看这个视频的第27:00(求树直径的原理和证明)

[video(video-iMl9BSet-1586583241905)(type-bilibili)(url-https://player.bilibili.com/player.html?aid=95472415)(image-https://ss.csdn.net/p?http://i0.hdslb.com/bfs/archive/5424cdb28ca513d905dc860808d8ea69fa389d1e.jpg)(title-第四届蓝桥杯a组)]

证明:
在这里插入图片描述
我们可以看出图中,树的直径是(4->2->5),长度为9.
我们一开始选定一个点dfs
如果是直径外一点,比如w1,从w1进行dfs找到的就是点4,路径就1->2->4,这个路径一定会与树的直径相交,而找到的4是直径的一端,那从4再进行dfs就是树的直径的另一端5,这样两遍dfs你就找到了树的直径
如果是直径内一点,比如w2,从w2开始dfs找到的最远点4,这个路径会被包含在树的直径里,那找到的点也就是树直径的一端,再dfs就可以找到另一端。
综上用两遍dfs就可以找到树的直径

代码:

网上找的模板:

#include <bits/stdc++.h>
using namespace std;


#define INF 10000000000

vector <int > G[1000005];
vector<int > E[1000005];
bool vis[1000005];
int d[1000005];

void init() {
    memset(vis, 0, sizeof(vis));
} 

void dfs(int u) {
    vis[u] = 1;
    int size = G[u].size();        //与顶点u相连的点数 

    for (int i = 0; i<size; i++) {            //对与顶点u相连的点数进行扫描 
        int v = G[u][i];
        if (!vis[v]) {
            d[v] = d[u] + E[u][i];
            dfs(v);
        }
    }
}

int main() {
    int n;
    cin >> n;
    int u, v, w;
    for (int i = 0; i<n-1; i++) {        //建立树过程 
        scanf("%d%d%d",&u,&v,&w);
        G[u-1].push_back(v-1);                //顶点两边都要记录 
        E[u-1].push_back(w);
        G[v-1].push_back(u-1);
        E[v-1].push_back(w);
    }

    init();
    for (int i = 0; i<n; i++)    d[i] = (i == 0?0:INF);
    dfs(0);
    int start = 0;
    int max = -1;
    for (int i = 0; i<n; i++) {
        if (d[i] > max && d[i] != INF) {
            max = d[i];
            start = i;
        }
    }

    init();
    for (int i = 0; i<n; i++)    d[i] = (i == start?0:INF);
    dfs(start);
    int ans = -1;
    for (int i = 0; i<n; i++) {
        if (d[i] > ans && d[i] != INF) {
            ans = d[i];
        }
    }

    //ans = 10*ans + ans*(ans+1)/2;
    cout << ans << endl;                    //ans  即为直径 
    return 0;
}