题意:
        求一棵树的最长路径,即求树的直径。
        
        
方法一:
一次dfs

思路:
        从任意节点出发(为了方便,这里可以从一号节点出发)。
        遍历每个节点的儿子节点,寻找儿子节点中的最大值和次大值,
          将这两个值之和作为路径的总长度(即最大值和次大值作为一条路径的两份)。
        res 维护路径的最大值。

例子:

    

#define ll long long

class Solution {
public:
    ll res=0;//维护最大值
    long long solve(int n, vector<int>& u, vector<int>& v, vector<int>& w) {
        vector<vector<pair<int,int>>> g(n+1);
        for(int i=0;i<n-1;i++){//建树
            g[u[i]].push_back({v[i],w[i]});
            g[v[i]].push_back({u[i],w[i]});
        }
        dfs(1,1,g);
        return res;
    }
    ll dfs(int x,int fa,vector<vector<pair<int,int>>> g){
        int num=g[x].size();
        ll s1=0,s2=0;//s1,s2分别表示当前节点x的儿子节点中最大值和次大值
        for(int i=0;i<num;i++){//遍历从节点x出发的其他节点

            auto t=g[x][i];
            int y=t.first,z=t.second;
            if(y!=fa){//未访问过
                int val=dfs(y,x,g)+z;
                if(s1<val){//维护最大值
                    s2=s1;
                    s1=val;
                  
                }else if(s2<val){//维护次大值
                    s2=val;
                }
            }
        }
        res=max(res,s1+s2);//维护最长路径的最大值
        return s1;
    }
};

时间复杂度:
空间复杂度:



方法二:
  两次dfs

思路:
        从任意节点 u 出发,第一次深搜到最远节点 v ,(节点 v 是最长路径的其中一个端点),
        然后再从节点 v 出发,第二次深搜到最远节点 w,(节点 u 是最长路径的另外一个端点)。
        所以以节点 v 和节点 u为端点的直线为最长路径(树的直径)。 

#define ll long long

class Solution {
public:
   
    ll ma=0;//维护最大值
    ll id;//维护最大值的节点编号
    long long solve(int n, vector<int>& u, vector<int>& v, vector<int>& w) {
        vector<vector<pair<int,int>>> g(n+1);
        for(int i=0;i<n-1;i++){//建树
            g[u[i]].push_back({v[i],w[i]});
            g[v[i]].push_back({u[i],w[i]});
        }
        dfs(1,1,g,0);//第一次可以从任意节点深搜
        ma=0;
        dfs(id,id,g,0);//第二次只能从id节点(即第一次深搜的结果)深搜
        return ma;
    }
    void dfs(int x,int fa,vector<vector<pair<int,int>>> g,ll s){
        int num=g[x].size();
        
        for(int i=0;i<num;i++){//遍历从节点x出发的其他节点
            auto t=g[x][i];
            int y=t.first,z=t.second;
            if(y!=fa){//未访问过
                dfs(y,x,g,s+z);
                if(ma<s+z){//维护距离的最大值ma
                    ma=s+z;
                    id=y;
                }
            }
        }
        
        return;
    }
};

时间复杂度:
空间复杂度: