Maximum difference between node and its ancestor in a Directed Acyclic Graph ( DAG ) - GeeksforGeeks

14 Sep, 2021
Given a 2D array Edges[][], representing a directed edge between the pair of nodes in a Directed Acyclic Connected Graph consisting of N nodes valued from [1, N] and an array arr[] representing weights of each node, the task is to find the maximum absolute difference between the weights of any node and any of its ancestors.
Examples:
Input: N = 5, M = 4, Edges[][2] = {{1, 2}, {2, 3}, {4, 5}, {1, 3}}, arr[] = {13, 8, 3, 15, 18}Output: 10Explanation:
From the above graph, it can be observed that the maximum difference between the value of any node and any of its ancestors is 18 (Node 5) – 8 (Node 2) = 10.
Input: N = 4, M = 3, Edges[][2] = {{1, 2}, {2, 4}, {1, 3}}, arr[] = {2, 3, 1, 5}Output: 3
Approach: The idea to solve the given problem is to perform DFS Traversal on the Graph and populate the maximum and minimum values from each node to its child node and find the maximum absolute difference.Follow the steps below to solve the given problem:
Initialize a variable, say ans as INT_MIN to store the required maximum difference.
Perform DFS traversal on the given graph to find the maximum absolute difference between the weights of a node and any of its ancestors by performing the following operations:For each source node, say src, update the value of ans to store the maximum of the absolute difference between the weight of src and currentMin and currentMax respectively.Update the value of currentMin as the minimum of currentMin and the value of the source node src.Update the value of currentMax as the maximum of currentMax and the value of the source node src.Now, recursively traverse the child nodes of src and update values of currentMax and currentMin as DFS(child, Adj, ans, currentMin, currentMax).
For each source node, say src, update the value of ans to store the maximum of the absolute difference between the weight of src and currentMin and currentMax respectively.
Update the value of currentMin as the minimum of currentMin and the value of the source node src.
Update the value of currentMax as the maximum of currentMax and the value of the source node src.
Now, recursively traverse the child nodes of src and update values of currentMax and currentMin as DFS(child, Adj, ans, currentMin, currentMax).
After completing the above steps, print the value of ans as the resultant maximum difference.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program for the above approach#include <bits/stdc++.h>using namespace std; // Function to perform DFS// Traversal on the given graphvoid DFS(int src, vector<int> Adj[],         int& ans, int arr[],         int currentMin, int currentMax){     // Update the value of ans    ans = max(        ans, max(abs(                     currentMax - arr[src - 1]),                 abs(currentMin - arr[src - 1])));     // Update the currentMin and currentMax    currentMin = min(currentMin,                     arr[src - 1]);     currentMax = min(currentMax,                     arr[src - 1]);     // Traverse the adjacency    // list of the node src    for (auto& child : Adj[src]) {         // Recursively call        // for the child node        DFS(child, Adj, ans, arr,            currentMin, currentMax);    }} // Function to calculate maximum absolute// difference between a node and its ancestorvoid getMaximumDifference(int Edges[][2],                          int arr[], int N,                          int M){     // Stores the adjacency list of graph    vector<int> Adj[N + 1];     // Create Adjacency list    for (int i = 0; i < M; i++) {        int u = Edges[i][0];        int v = Edges[i][1];         // Add a directed edge        Adj[u].push_back(v);    }     int ans = 0;     // Perform DFS Traversal    DFS(1, Adj, ans, arr,        arr[0], arr[0]);     // Print the maximum    // absolute difference    cout << ans;} // Driver Codeint main(){    int N = 5, M = 4;    int Edges[][2]        = { { 1, 2 }, { 2, 3 },            { 4, 5 }, { 1, 3 } };    int arr[] = { 13, 8, 3, 15, 18 };     getMaximumDifference(Edges, arr, N, M);     return 0;}
// Java program for the above approachimport java.util.*; class GFG{     static int ans; // Function to perform DFS// Traversal on the given graphstatic void DFS(int src,                ArrayList<ArrayList<Integer> > Adj,                int arr[], int currentMin,                int currentMax){         // Update the value of ans    ans = Math.max(ans,          Math.max(Math.abs(currentMax - arr[src - 1]),                   Math.abs(currentMin - arr[src - 1])));     // Update the currentMin and currentMax    currentMin = Math.min(currentMin, arr[src - 1]);     currentMax = Math.min(currentMax, arr[src - 1]);     // Traverse the adjacency    // list of the node src    for(Integer child : Adj.get(src))    {                 // Recursively call        // for the child node        DFS(child, Adj, arr, currentMin, currentMax);    }} // Function to calculate maximum absolute// difference between a node and its ancestorstatic void getMaximumDifference(int Edges[][],                                 int arr[], int N,                                 int M){    ans = 0;         // Stores the adjacency list of graph    ArrayList<ArrayList<Integer>> Adj = new ArrayList<>();     for(int i = 0; i < N + 1; i++)        Adj.add(new ArrayList<>());     // Create Adjacency list    for(int i = 0; i < M; i++)    {        int u = Edges[i][0];        int v = Edges[i][1];         // Add a directed edge        Adj.get(u).add(v);    }     // Perform DFS Traversal    DFS(1, Adj, arr, arr[0], arr[0]);     // Print the maximum    // absolute difference    System.out.println(ans);} // Driver codepublic static void main(String[] args){    int N = 5, M = 4;    int Edges[][] = { { 1, 2 }, { 2, 3 },                      { 4, 5 }, { 1, 3 } };    int arr[] = { 13, 8, 3, 15, 18 };     getMaximumDifference(Edges, arr, N, M);}} // This code is contributed by offbeat
# Python3 program for the above approachans = 0 # Function to perform DFS# Traversal on the given graphdef DFS(src, Adj, arr, currentMin, currentMax):         # Update the value of ans    global ans    ans = max(ans, max(abs(currentMax - arr[src - 1]),                       abs(currentMin - arr[src - 1])))     # Update the currentMin and currentMax    currentMin = min(currentMin, arr[src - 1])     currentMax = min(currentMax, arr[src - 1])     # Traverse the adjacency    # list of the node src    for child in Adj[src]:                 # Recursively call        # for the child node        DFS(child, Adj, arr, currentMin, currentMax) # Function to calculate maximum absolute# difference between a node and its ancestordef getMaximumDifference(Edges, arr, N, M):         global ans         # Stores the adjacency list of graph    Adj = [[] for i in range(N + 1)]     # Create Adjacency list    for i in range(M):        u = Edges[i][0]        v = Edges[i][1]         # Add a directed edge        Adj[u].append(v)     # Perform DFS Traversal    DFS(1, Adj, arr, arr[0], arr[0])     # Print the maximum    # absolute difference    print(ans) # Driver Codeif __name__ == '__main__':         N = 5    M = 4    Edges = [[1, 2], [2, 3], [4, 5], [1, 3]]    arr =  [13, 8, 3, 15, 18]         getMaximumDifference(Edges, arr, N, M) # This code is contributed by ipg2016107
// C# program for the above approachusing System;using System.Collections.Generic;class GFG {         static int ans;      // Function to perform DFS    // Traversal on the given graph    static void DFS(int src, List<List<int>> Adj, int[] arr,                    int currentMin, int currentMax)    {                  // Update the value of ans        ans = Math.Max(ans,              Math.Max(Math.Abs(currentMax - arr[src - 1]),                       Math.Abs(currentMin - arr[src - 1])));              // Update the currentMin and currentMax        currentMin = Math.Min(currentMin, arr[src - 1]);              currentMax = Math.Min(currentMax, arr[src - 1]);              // Traverse the adjacency        // list of the node src        foreach(int child in Adj[src])        {                          // Recursively call            // for the child node            DFS(child, Adj, arr, currentMin, currentMax);        }    }          // Function to calculate maximum absolute    // difference between a node and its ancestor    static void getMaximumDifference(int[,] Edges,                                     int[] arr, int N, int M)    {        ans = 0;                  // Stores the adjacency list of graph        List<List<int>> Adj = new List<List<int>>();              for(int i = 0; i < N + 1; i++)            Adj.Add(new List<int>());              // Create Adjacency list        for(int i = 0; i < M; i++)        {            int u = Edges[i,0];            int v = Edges[i,1];                  // Add a directed edge            Adj[u].Add(v);        }              // Perform DFS Traversal        DFS(1, Adj, arr, arr[0], arr[0]);              // Print the maximum        // absolute difference        Console.WriteLine(ans);    }       static void Main() {    int N = 5, M = 4;    int[,] Edges = { { 1, 2 }, { 2, 3 },                      { 4, 5 }, { 1, 3 } };    int[] arr = { 13, 8, 3, 15, 18 };      getMaximumDifference(Edges, arr, N, M);  }} // This code is contributed by rameshtravel07.
<script> // Javascript program for the above approach var ans = 0; // Function to perform DFS// Traversal on the given graphfunction DFS(src, Adj, arr, currentMin, currentMax){     // Update the value of ans    ans = Math.max(        ans, Math.max(Math.abs(                     currentMax - arr[src - 1]),                 Math.abs(currentMin - arr[src - 1])));     // Update the currentMin and currentMax    currentMin = Math.min(currentMin,                     arr[src - 1]);     currentMax = Math.min(currentMax,                     arr[src - 1]);     // Traverse the adjacency    // list of the node src    Adj[src].forEach(child => {               // Recursively call        // for the child node        DFS(child, Adj,arr,            currentMin, currentMax);    });} // Function to calculate maximum absolute// difference between a node and its ancestorfunction getMaximumDifference(Edges, arr, N, M){     // Stores the adjacency list of graph    var Adj = Array.from(Array(N+1), ()=> Array());     // Create Adjacency list    for (var i = 0; i < M; i++) {        var u = Edges[i][0];        var v = Edges[i][1];         // Add a directed edge        Adj[u].push(v);    }     // Perform DFS Traversal    DFS(1, Adj, arr,        arr[0], arr[0]);     // Print the maximum    // absolute difference    document.write( ans);} // Driver Codevar N = 5, M = 4;var Edges    = [ [ 1, 2 ], [ 2, 3 ],        [ 4, 5 ], [ 1, 3 ] ];var arr = [13, 8, 3, 15, 18];getMaximumDifference(Edges, arr, N, M); </script>
10
 
Time Complexity: O(N + M)Auxiliary Space: O(N)
 
ipg2016107
offbeat
rrrtnx
rameshtravel07
DFS
Data Structures
Graph
Recursion
Searching
Technical Scripter
Data Structures
Searching
Recursion
DFS
Graph
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Data Structures | Linked List | Question 5
Data Structures | Tree Traversals | Question 4
Data Structures | Linked List | Question 6
Difference between Singly linked list and Doubly linked list
Advantages and Disadvantages of Linked List
Breadth First Search or BFS for a Graph
Depth First Search or DFS for a Graph
Dijkstra's shortest path algorithm | Greedy Algo-7
Kruskal’s Minimum Spanning Tree Algorithm | Greedy Algo-2
Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5