找到图中的最长路径

算法:

可以利用以下算法找到图中距离最远的两个节点与它们之间的路径

  • 从任意节点 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 }
复制代码

 

posted @   r1-12king  阅读(755)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示