如何求解从源点u出发恰好经过k条边的最短路径(不限终点)?
Hey there! Let's adjust your existing code to solve the problem of finding the shortest path starting from node u that uses exactly k edges—regardless of which node it ends at.
Understanding the Original Code
Your current shortestPath function calculates the shortest path from u to a specific v using exactly k edges. To adapt this, we just need to compute this value for all possible end nodes and then take the minimum of those results.
Modified Implementation
Here's how you can tweak the code:
- Keep the core recursive function (we'll reuse it to calculate paths to each end node).
- Add a wrapper function that iterates over all possible end nodes, computes the shortest path to each with exactly
kedges, and returns the smallest value.
def shortestPath(graph, u, v, k): V = len(graph) INF = 999999999999 # Base cases if k == 0 and u == v: return 0 if k == 1 and graph[u][v] != INF: return graph[u][v] if k <= 0: return INF # Initialize result to infinity res = INF # Iterate through all adjacent nodes of u for i in range(V): if graph[u][i] != INF and u != i: rec_res = shortestPath(graph, i, v, k - 1) if rec_res != INF: res = min(res, graph[u][i] + rec_res) return res def shortestPathExactlyKEdgesFromU(graph, u, k): V = len(graph) INF = 999999999999 min_total = INF # Check all possible end nodes for v in range(V): path_len = shortestPath(graph, u, v, k) if path_len < min_total: min_total = path_len return min_total if min_total != INF else -1 # Return -1 if no such path exists # Driver code if __name__ == '__main__': INF = 999999999999 graph = [[0, 4, 2, 6, 5], [INF, 0, 4, 2, 5], [INF, INF, 0, 4, 3], [INF, INF, INF, 0, 3], [INF, INF, INF, INF, 0]] u = 0 k = 3 result = shortestPathExactlyKEdgesFromU(graph, u, k) if result == -1: print("No valid path with exactly", k, "edges exists from node", u) else: print("Weight of the shortest path with exactly", k, "edges from node", u, "is", result)
Key Changes Explained
- Wrapper Function:
shortestPathExactlyKEdgesFromUloops through every possible end nodev, uses your original function to get the path length fromutovwithkedges, and tracks the minimum value. - Dynamic V Value: Instead of hardcoding
V=4, we uselen(graph)to make the code work for any graph size. - Edge Case Handling: If no valid path exists (all results are INF), we return
-1and print a clear message.
Optimization Note
The recursive approach has a time complexity of O(V^k), which can get slow for large graphs or large k. For better performance, consider using a dynamic programming approach:
- Create a DP table where
dp[m][j]represents the shortest path fromutojusing exactlymedges. - Initialize
dp[0][u] = 0(0 edges, stay at u) and all otherdp[0][j] = INF. - For each step from 1 to k, update
dp[m][j] = min(dp[m-1][i] + graph[i][j])for all nodesi. - The answer is the minimum value in
dp[k][*].
Here's a quick DP implementation example:
def shortestPathExactlyKEdgesDP(graph, u, k): V = len(graph) INF = 999999999999 # Initialize DP table: dp[m][j] = shortest path from u to j with m edges dp = [[INF] * V for _ in range(k+1)] dp[0][u] = 0 # 0 edges, start at u for m in range(1, k+1): for j in range(V): for i in range(V): if dp[m-1][i] != INF and graph[i][j] != INF: dp[m][j] = min(dp[m][j], dp[m-1][i] + graph[i][j]) min_total = min(dp[k]) return min_total if min_total != INF else -1 # Use it in driver code: # result = shortestPathExactlyKEdgesDP(graph, u, k)
This DP approach runs in O(k*V²) time, which is much more efficient for larger inputs.
内容的提问来源于stack exchange,提问作者Mayank Kataria

