1245. 树的直径(拓扑排序+BFS)
1245. 树的直径
给你这棵「无向树」,请你测算并返回它的「直径」:这棵树上最长简单路径的 边数。
我们用一个由所有「边」组成的数组 edges 来表示一棵无向树,其中 edges[i] = [u, v] 表示节点 u 和 v 之间的双向边。
树上的节点都已经用 {0, 1, ..., edges.length} 中的数做了标记,每个节点上的标记都是独一无二的。
示例 1:

输入:edges = [[0,1],[0,2]] 输出:2 解释: 这棵树上最长的路径是 1 - 0 - 2,边数为 2。
示例 2:

输入:edges = [[0,1],[1,2],[2,3],[1,4],[4,5]] 输出:4 解释: 这棵树上最长的路径是 3 - 2 - 1 - 4 - 5,边数为 4。
提示:
0 <= edges.length < 10^4edges[i][0] != edges[i][1]0 <= edges[i][j] <= edges.lengthedges会形成一棵无向树
1 class Solution { 2 public: 3 int treeDiameter(vector<vector<int>>& edges) { 4 int n = edges.size() + 1; 5 vector<vector<int>> grap(n); 6 vector<int> degree(n); 7 // 构建无向图 8 for(auto &edge : edges){ 9 grap[edge[0]].push_back(edge[1]); 10 grap[edge[1]].push_back(edge[0]); 11 degree[edge[0]]++; 12 degree[edge[1]]++; 13 } 14 15 queue<int> q; 16 for (unsigned int i = 0; i < degree.size(); i++) { 17 // 将叶子节点(度为1)入队 18 if (degree[i] == 1) { 19 q.push(i); 20 } 21 } 22 int level = 0; // 处理节点层数 23 int count = n; // 剩余节点数 24 while (count > 2) { // 剩余节点数小于等于2时找到直径 25 int size = q.size(); 26 for (int i = 0; i < size; i++) { 27 int curNode = q.front(); 28 q.pop(); 29 degree[curNode]--; 30 count--; 31 // 剪枝,删除与当前节点相连的边(相连边的对端节点的度--) 32 for (auto &peerNode : grap[curNode]) { 33 degree[peerNode]--; // 与当前处理节点相连边对端节点的度--(剪枝) 34 if (degree[peerNode] == 1) { // 叶子节点入队列 35 q.push(peerNode); 36 } 37 } 38 } 39 level++; 40 } 41 // 剩余节点为2时直径的边数(层数*2)需要再加上1条边(剩余2个节点可以形成一条边) 42 return (count % 2 == 0) ? (level * 2 + 1) : level * 2; 43 } 44 };
浙公网安备 33010602011771号