后序遍历
(1)跟[二叉树的最大路径和]一个思路,不同的是这里树不一定是二叉;
(2)注意,起始根结点不一定是0,只要是叶子节点都可以作为根结点进行计算,另外边也不一定是从父节点到子节点,看用什么做根,所以邻接表需要无向边,而不是有向边。
/** * struct Interval { * int start; * int end; * }; */ class Solution { public: struct Node{ int v; int dis; Node(int _v, int _dis):v(_v), dis(_dis){} }; int ans = 0; int start; //根结点 vector<vector<Node>> Adj; /** * 树的直径 * @param n int整型 树的节点个数 * @param Tree_edge Interval类vector 树的边 * @param Edge_value int整型vector 边的权值 * @return int整型 */ int solve(int n, vector<Interval>& Tree_edge, vector<int>& Edge_value) { // write code here Adj.resize(n); for(int i = 0; i < n - 1; i ++){ int u = Tree_edge[i].start, v = Tree_edge[i].end; int dis = Edge_value[i]; Adj[u].push_back(Node(v, dis)); Adj[v].push_back(Node(u, dis)); } for(int i = 0; i < n; i ++){ //找起始点 if(Adj[i].size() == 1){ start = i; break; } } postOrder(start, -1); return ans; } int postOrder(int u, int parent){ if(Adj[u].size() == 1 && u != start) return 0; vector<int> vec; for(int i = 0; i < Adj[u].size(); i ++){ int v = Adj[u][i].v, dis = Adj[u][i].dis; if(v == parent) continue; int dist = postOrder(v, u) + dis; vec.push_back(dist); } sort(vec.begin(), vec.end()); int n = vec.size(); ans = max(ans, vec[n - 1] + (n > 1 ? vec[n - 2] : 0)); return vec[n - 1]; } };