Longest path in directed acyclic graph PART1
Given a weighted directed acyclic graph DAG and a source point s in it, find the longest distance from s to all other vertices in the given graph
The longest path problem of general graphs is not as easy as the shortest path problem, because the longest path problem does not have the attribute of optimal substructure. In fact, the longest path problem is NP hard for general graphs. However, for the longest path problem of directed acyclic graphs, it has a linear time solution. This idea is similar to the linear time solution of the shortest path in a directed acyclic graph. We use topological sorting.
We initialize the distance to all vertices to negative infinity and the distance to the source point to 0, and then we find the topological order of the graph. The topological sorting of a graph represents the linear sorting of the graph (Fig. b is the linear representation of Fig. a). Once we have a topological order (or linear representation), we process all vertices one by one according to the topological order. For each vertex being processed, we update its adjacent distance with the distance of the current vertex.
The following figure shows the detailed process of finding the longest path.
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-toj1ljwi-1628475265234) (D: \ dev \ srccode \ geek algorithm leetcode \ SRC \ main \ leetcode_manuscripts \ graph \ longest path in the directed acyclic graph - Part1. Assets \ image-202108095700517. PNG)]
Alogrithm:
The following is a complete algorithm for finding the longest distance.
- Initialize dist[] = {NINF, NINF,...} and dist[s] = 0, where s is the source vertex. Here NINF represents negative infinity.
- Creates the topological order of all vertices.
- Do the following for each vertex u in topological order.
...... Track each adjacent vertex v of u
..................if (dist[v] < dist[u] + weight(u, v))
...........................dist[ v] = dist[u] + weight(u, v)
Code:
static class _4th_1 { static class AdjListNode { int v; int w; public AdjListNode(int v, int w) { this.v = v; this.w = w; } public int getV() { return v; } public int getW() { return w; } } static class Graph { int V; List<List<AdjListNode>> adj; public Graph(int V) { this.V = V; adj = new ArrayList<>(V); for (int i = 0; i < V; i++) { adj.add(new ArrayList<>()); } } void addEdge(int u, int v, int w) {//Adding edges, digraph AdjListNode node = new AdjListNode(v, w); adj.get(u).add(node); } void topologicalSortUtil(int v, boolean[] visited, Stack<Integer> stack) { visited[v] = true;//The current node is marked as visited for (AdjListNode node : adj.get(v)) {//Traverse the adjacent nodes of the current node if (!visited[node.getV()]) { topologicalSortUtil(node.getV(), visited, stack); } } stack.push(v); } final static Integer NINF = Integer.MIN_VALUE; void longestPath(int s) { Stack<Integer> stack = new Stack<>(); int[] dist = new int[V]; boolean[] visited = new boolean[V]; //Do topology sorting first for (int i = 0; i < V; i++) { if (!visited[i]) topologicalSortUtil(i, visited, stack); } Arrays.fill(dist, NINF); dist[s] = 0;//Initialize source point s //Traversing adjacent nodes of a node while (!stack.isEmpty()) { int u = stack.pop(); if (dist[u] != NINF) { for (AdjListNode vNode : adj.get(u)) { int v = vNode.getV(), w = vNode.getW(); if (dist[v] < dist[u] + w) { dist[v] = dist[u] + w; } } } } //Print longest path for (int i = 0; i < V; i++) if (dist[i] == NINF) System.out.print("INF "); else System.out.print(dist[i] + " "); } public static void main(String args[]) { // Create a graph given in the above diagram. // Here vertex numbers are 0, 1, 2, 3, 4, 5 with // following mappings: // 0=r, 1=s, 2=t, 3=x, 4=y, 5=z Graph g = new Graph(6); g.addEdge(0, 1, 5); g.addEdge(0, 2, 3); g.addEdge(1, 3, 6); g.addEdge(1, 2, 2); g.addEdge(2, 4, 4); g.addEdge(2, 5, 2); g.addEdge(2, 3, 7); g.addEdge(3, 5, 1); g.addEdge(3, 4, -1); g.addEdge(4, 5, -2); int s = 1; System.out.print("Following are longest distances from source vertex " + s + " \n"); g.longestPath(s); /** * Following are longest distances from source vertex 1 * INF 0 2 9 8 */ } } }
Time complexity
- The time complexity of topology sorting is O ( V + E ) O(V+E) O(V+E). After finding the topological order, the algorithm processes all vertices, and for each vertex, it runs a loop for all adjacent vertices. The total adjacent vertices in the graph are O ( E ) O(E) O(E). Therefore, the inner loop runs $O(V+E) $times. Therefore, the overall time complexity of the algorithm is O ( V + E ) O(V+E) O(V+E).