712030. Shortest path in Directed Acyclic Graph
Shortest Path in Directed Acyclic Graph
Slug: shortest-path-in-directed-acyclic-graph
Difficulty: Medium
Id: 712030
Topic Tags: Graph, Shortest Path, Data Structures, Algorithms
Company Tags: None
Summary
In this problem, we are given a directed acyclic graph (DAG) and asked to find the shortest path from a source node to all other nodes in the graph. This is an extension of the classic shortest path problem for undirected graphs, where we need to consider the direction of edges in the graph.
Detailed Explanation
To solve this problem, we can use topological sorting and Dijkstra's algorithm. Topological sorting is used to ensure that we visit all nodes in the correct order, while Dijkstra's algorithm finds the shortest path from the source node to each node.
Here's a step-by-step breakdown of the solution:
- First, we perform a topological sort on the graph to get an ordering of the nodes.
- Then, for each node
vin the graph, we use Dijkstra's algorithm to find the shortest path from the source nodestov. We keep track of the distance fromstovand the previous node in the shortest path. - Finally, we return the distances and previous nodes for all nodes in the graph.
Here's an ASCII art diagram illustrating the algorithm:
+--------+
| s |
+--------+
|
| (topological sort)
+--------+
| v1 |
+--------+
|
| (Dijkstra's algorithm)
+--------+
| v2 |
+--------+
|
| ...
Time complexity: O(|E|log|V|) where |E| is the number of edges and |V| is the number of nodes.
Space complexity: O(|V| + |E|).
Optimized Solutions
Java
import java.util.*;
public class ShortestPathInDAG {
public static Map<Integer, Integer> shortestPath(int[][] graph) {
// Perform topological sort
List<Integer> order = new ArrayList<>();
for (int i = 0; i < graph.length; i++) {
if (!hasIncomingEdges(graph, i)) {
order.add(i);
}
}
Map<Integer, Integer> distances = new HashMap<>();
Map<Integer, Integer> previousNodes = new HashMap<>();
// Run Dijkstra's algorithm for each node in the graph
for (int v : order) {
distances.put(v, 0);
previousNodes.put(v, null);
for (int w : getNeighbors(graph, v)) {
int weight = getEdgeWeight(graph, v, w);
if (!distances.containsKey(w) || distances.get(w) > distances.get(v) + weight) {
distances.put(w, distances.get(v) + weight);
previousNodes.put(w, v);
}
}
}
return distances;
}
// Helper methods
private static boolean hasIncomingEdges(int[][] graph, int node) {
for (int i = 0; i < graph.length; i++) {
if (graph[i][node] > 0) {
return true;
}
}
return false;
}
private static List<Integer> getNeighbors(int[][] graph, int node) {
List<Integer> neighbors = new ArrayList<>();
for (int i = 0; i < graph.length; i++) {
if (graph[i][node] > 0) {
neighbors.add(i);
}
}
return neighbors;
}
private static int getEdgeWeight(int[][] graph, int u, int v) {
// Assume edge weight is 1
return 1;
}
}