找到图中的最长路径
算法:
可以利用以下算法找到图中距离最远的两个节点与它们之间的路径
- 从任意节点 p 出发,利用广度优先搜索或者深度优先搜索找到以p为起点的最长路径的终点x;
- 以节点 x 出发,找到以 x 为起点的最长路径的终点 y;
- x 到 y 之间的路径即为图中的最长路径
上述算法的证明可以参考「算法导论习题解答 9-1」
广度优先搜索
python
1 class Solution: 2 def getMaxPath(self, n, edges): 3 g = [[] for _ in range(n)] 4 for x, y in edges: 5 g[x].append(y) 6 g[y].append(x) 7 8 parent = [0] * False 9 10 def bfs(start): 11 global node 12 vis = [False] * n 13 vis[start] = True 14 q = deque([start]) 15 while q: 16 node = q.popleft() 17 for nd in g[node]: 18 if not vis[nd]: 19 vis[nd] = True 20 q.append(nd) 21 parent[nd] = node 22 return node 23 24 x = bfs(0) 25 y = bfs(x) 26 27 path = [] 28 parent[x] = -1 29 while y != -1: 30 path.append(y) 31 y = parent[y] 32 33 return path
java:
1 class Solution { 2 public List<Integer> find(int n, int[][] edges) { 3 List<Integer> ans = new ArrayList<Integer>(); 4 List<Integer>[] adj = new List[n]; 5 for (int i = 0; i < n; i++) { 6 adj[i] = new ArrayList<Integer>(); 7 } 8 for (int[] edge : edges) { 9 adj[edge[0]].add(edge[1]); 10 adj[edge[1]].add(edge[0]); 11 } 12 13 int[] parent = new int[n]; 14 Arrays.fill(parent, -1); 15 /* 找到与节点 0 最远的节点 x */ 16 int x = findLongestNode(0, parent, adj); 17 /* 找到与节点 x 最远的节点 y */ 18 int y = findLongestNode(x, parent, adj); 19 /* 求出节点 x 到节点 y 的路径 */ 20 List<Integer> path = new ArrayList<Integer>(); 21 parent[x] = -1; 22 while (y != -1) { 23 path.add(y); 24 y = parent[y]; 25 } 26 return path; 27 } 28 29 public int findLongestNode(int u, int[] parent, List<Integer>[] adj) { 30 int n = adj.length; 31 Queue<Integer> queue = new ArrayDeque<Integer>(); 32 boolean[] visit = new boolean[n]; 33 queue.offer(u); 34 visit[u] = true; 35 int node = -1; 36 37 while (!queue.isEmpty()) { 38 int curr = queue.poll(); 39 node = curr; 40 for (int v : adj[curr]) { 41 if (!visit[v]) { 42 visit[v] = true; 43 parent[v] = curr; 44 queue.offer(v); 45 } 46 } 47 } 48 return node; 49 } 50 }
深度优先搜索
python
1 class Solution: 2 def getMaxPath2(self, n, edges): 3 g = [[] for _ in range(n)] 4 for x, y in edges: 5 g[x].append(y) 6 g[y].append(x) 7 parents = [0] * n 8 maxDepth, node = 0, -1 9 10 def dfs(x, pa, depth): 11 nonlocal maxDepth, node 12 if depth > maxDepth: 13 maxDepth, node = depth, x 14 parents[x] = pa 15 for y in g[x]: 16 if y != pa: 17 dfs(y, x, depth + 1) 18 19 dfs(0, -1, 1) 20 maxDepth = 0 21 dfs(node, -1, 1) 22 23 path = [] 24 while node != -1: 25 path.append(node) 26 node = parents[node] 27 28 return path
java
1 class Solution { 2 public List<Integer> findMinHeightTrees(int n, int[][] edges) { 3 List<Integer>[] adj = new List[n]; 4 for (int i = 0; i < n; i++) { 5 adj[i] = new ArrayList<Integer>(); 6 } 7 for (int[] edge : edges) { 8 adj[edge[0]].add(edge[1]); 9 adj[edge[1]].add(edge[0]); 10 } 11 12 int[] parent = new int[n]; 13 Arrays.fill(parent, -1); 14 /* 找到与节点 0 最远的节点 x */ 15 int x = findLongestNode(0, parent, adj); 16 /* 找到与节点 x 最远的节点 y */ 17 int y = findLongestNode(x, parent, adj); 18 /* 求出节点 x 到节点 y 的路径 */ 19 List<Integer> path = new ArrayList<Integer>(); 20 parent[x] = -1; 21 while (y != -1) { 22 path.add(y); 23 y = parent[y]; 24 } 25 return path; 26 } 27 28 public int findLongestNode(int u, int[] parent, List<Integer>[] adj) { 29 int n = adj.length; 30 int[] dist = new int[n]; 31 Arrays.fill(dist, -1); 32 dist[u] = 0; 33 dfs(u, dist, parent, adj); 34 int maxdist = 0; 35 int node = -1; 36 for (int i = 0; i < n; i++) { 37 if (dist[i] > maxdist) { 38 maxdist = dist[i]; 39 node = i; 40 } 41 } 42 return node; 43 } 44 45 public void dfs(int u, int[] dist, int[] parent, List<Integer>[] adj) { 46 for (int v : adj[u]) { 47 if (dist[v] < 0) { 48 dist[v] = dist[u] + 1; 49 parent[v] = u; 50 dfs(v, dist, parent, adj); 51 } 52 } 53 } 54 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧