Open In App

Minimum path need to reverse to reach each node in a tree from each vertex

Last Updated : 24 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a directed tree consisting of N nodes valued from [0, N – 1] and M edges, the task is to find the minimum number of edges that need to reverse for each node X such that there is a path from node X to each vertex of the given Tree.

Examples:

Input: N = 6, edges[][] = {{0, 1}, {1, 3}, {2, 3}, {4, 0}, {4, 5}}
Output: 2 2 2 3 1 2
Explanation:
The answer for node 0 is 2, which can be calculated as:

From 0 to 0: No edges are required to reverse to reach 0 from 0.
From 0 to 1: Can be reached directly using edge 0 -> 1.
From 0 to 2: The edge 2 -> 3 must be reversed for the path 0 -> 1 -> 3 -> 2 to reach 2 from node 0.
From 0 to 3: Can be reached directly as 0 -> 1 -> 3.
From 0 to 4: The edge 4 -> 0 must be reversed to reach 4 from node 0.
From 0 to 5: The edge 4 -> 0 must be reversed to reach 5 from node 0 as 0 -> 4 -> 5

To reach every node from the node 0, edge 2 -> 3 and edge 4 -> 0 is reversed. So, a total of 2 edges is reversed for node 0. Similarly, the ans for all the nodes can be calculated.

Input: N = 5, edges[][] = {{1, 0}, {1, 2}, {3, 2}, {3, 4}}
Output: 2 1 2 1 2

Approach: To solve the above problem, the idea is to store the directed edge in the adjacency list along with the reversed directed edge with the negative sign i.e. for directed edge a -> b store the edge a -> b and b -> -a. Then, for each node X of the tree, the answer can be calculated as the number of negative edges encountered in the simple Depth For Search(DFS) from that node X.Follow the steps below to solve the problem:

  • Initialize a 2-dimensional vector, say graph[][], to store the edges of the graph.
  • Traverse the array edges[][] and for each pair (a, b), push the directed edge b in graph[a] and reversed directed edge -a in graph[b].
  • Iterate over the range N, and for each node:
    • Initialize a variable, say count = 0, to count the required number of edges to reverse.
    • Call a recursive function, say reorderPaths(node, graph, count, visited) to perform the DFS on the tree.
    • Increase the value of count for each of the negative edges traversed in the DFS.
    • Print the value of the count, for each iteration of the node.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
  
#include <bits/stdc++.h>
using namespace std;
  
// Function to perform the DFS traversal
// of the tree with reordered paths
void reorderPaths(
    int s, vector<vector<int> > graph,
    int& count, vector<bool>& visited)
{
    visited[s] = true;
  
    // Traverse the adjacency list of
    // the source node
    for (auto i : graph[s]) {
  
        if (!visited[abs(i)]) {
  
            // Reorder the path
            if (i < 0)
                count++;
  
            // Recursively Call DFS
            reorderPaths(abs(i), graph,
                         count, visited);
        }
    }
}
  
// Function to find minimum edges to
// reverse to make the tree vertices
// reachable for each node
void minReorder(int n, vector<vector<int> > edges)
{
    // Stores the edges
    vector<vector<int> > graph(n);
  
    // Traversing the childs
    for (int i = 0; i < edges.size(); i++) {
        int a = edges[i][0];
        int b = edges[i][1];
  
        // Storing the direct edge
        graph[a].push_back(b);
  
        // Storing the reverse edge
        graph[b].push_back(-a);
    }
  
    // Finding ans for each node
    for (int i = 0; i < n; i++) {
        vector<bool> visited(n, false);
        int count = 0;
  
        // Function Call
        reorderPaths(i, graph, count, visited);
        cout << count << " ";
    }
}
  
// Driver Code
int main()
{
    int N = 6;
    vector<vector<int> > edges
        = { { 0, 1 }, { 1, 3 }, { 2, 3 }, { 4, 0 }, { 4, 5 } };
    minReorder(N, edges);
  
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
  
public class GFG{
static int count;
    
// Function to perform the DFS traversal
// of the tree with reordered paths
static void reorderPaths(
    int s, Vector<Integer>[] graph, boolean[] visited)
{
    visited[s] = true;
  
    // Traverse the adjacency list of
    // the source node
    for (int i : graph[s]) {
  
        if (!visited[(Math.abs(i))]) {
  
            // Reorder the path
            if (i < 0)
                count++;
  
            // Recursively Call DFS
            reorderPaths(Math.abs(i), graph, visited);
        }
    }
}
  
// Function to find minimum edges to
// reverse to make the tree vertices
// reachable for each node
static void minReorder(int n, int [][] edges)
{
    
    // Stores the edges
    Vector<Integer>[] graph = new Vector[n];
    for (int i = 0; i < n; i++) 
        graph[i] = new Vector<>();
    
    // Traversing the childs
    for (int i = 0; i < edges.length; i++) {
  
        int a = edges[i][0];
        int b = edges[i][1];
  
        // Storing the direct edge
        graph[a].add(b);
  
        // Storing the reverse edge
        graph[b].add(-a);
    }
  
    // Finding ans for each node
    for (int i = 0; i < n; i++) {
        boolean []visited = new boolean[n];
        count = 0;
  
        // Function Call
        reorderPaths(i, graph,  visited);
        System.out.print(count+ " ");
    }
}
  
// Driver Code
public static void main(String[] args)
{
    int N = 6;
    int [][] edges
        = { { 0, 1 }, { 1, 3 }, { 2, 3 }, { 4, 0 }, { 4, 5 } };
    minReorder(N, edges);
  
}
}
  
// This code is contributed by 29AjayKumar


Python3




# Python 3 program for the above approach
count = 0
visited = []
  
# Function to perform the DFS traversal
# of the tree with reordered paths
def reorderPaths(s, graph):
    global count
    visited[s] = True
  
    # Traverse the adjacency list of
    # the source node
    for i in graph[s]:
        if(visited[abs(i)]==False):
            # Reorder the path
            if (i < 0):
                count += 1
  
            # Recursively Call DFS
            reorderPaths(abs(i), graph)
  
# Function to find minimum edges to
# reverse to make the tree vertices
# reachable for each node
def minReorder(n, edges):
    global count
    global visited
    # Stores the edges
    graph = [[] for i in range(n)]
  
    # Traversing the childs
    for i in range(len(edges)):
        a = edges[i][0]
        b = edges[i][1]
  
        # Storing the direct edge
        graph[a].append(b)
  
        # Storing the reverse edge
        graph[b].append(-a)
  
    # Finding ans for each node
    for i in range(n):
        visited = [False for i in range(n)]
        count = 0
  
        # Function Call
        reorderPaths(i, graph)
        print(count,end = " ")
  
# Driver Code
if __name__ == '__main__':
    N = 6
    edges = [[0, 1],[1, 3],[2, 3],[4, 0],[4, 5]]
    minReorder(N, edges)
      
    # This code is contributed by SURENDRA_GANGWAR.


C#




// C# code for above approach
using System;
using System.Collections.Generic;
  
public class GFG {
    static int count;
  
    // Function to perform the DFS traversal
    // of the tree with reordered paths
    static void ReorderPaths(int s, List<int>[] graph,
                             bool[] visited)
    {
        visited[s] = true;
  
        // Traverse the adjacency list of
        // the source node
        foreach(int i in graph[s])
        {
  
            if (!visited[(Math.Abs(i))]) {
  
                // Reorder the path
                if (i < 0)
                    count++;
  
                // Recursively Call DFS
                ReorderPaths(Math.Abs(i), graph, visited);
            }
        }
    }
  
    // Function to find minimum edges to
    // reverse to make the tree vertices
    // reachable for each node
    static void MinReorder(int n, int[][] edges)
    {
  
        // Stores the edges
        List<int>[] graph = new List<int>[ n ];
        for (int i = 0; i < n; i++)
            graph[i] = new List<int>();
  
        // Traversing the childs
        for (int i = 0; i < edges.Length; i++) {
  
            int a = edges[i][0];
            int b = edges[i][1];
  
            // Storing the direct edge
            graph[a].Add(b);
  
            // Storing the reverse edge
            graph[b].Add(-a);
        }
  
        // Finding ans for each node
        for (int i = 0; i < n; i++) {
            bool[] visited = new bool[n];
            count = 0;
  
            // Function Call
            ReorderPaths(i, graph, visited);
            Console.Write(count + " ");
        }
    }
  
    // Driver Code
    public static void Main(string[] args)
    {
        int N = 6;
        int[][] edges
            = { new int[] { 0, 1 }, new int[] { 1, 3 },
                new int[] { 2, 3 }, new int[] { 4, 0 },
                new int[] { 4, 5 } };
  
        MinReorder(N, edges);
    }
}
  
// This code is contributed by Vaibhav.


Javascript




<script>
    // Javascript program for the above approach
      
    // Function to perform the DFS traversal
    // of the tree with reordered paths
      
    let graph;
    let edges;
    let count;
    let visited;
      
    function reorderPaths(s)
    {
        visited[s] = true;
  
        // Traverse the adjacency list of
        // the source node
        for(let i  = 0; i < graph[s].length; i++) {
  
            if (!visited[(Math.abs(graph[s][i]))]) {
  
                // Reorder the path
                if (graph[s][i] < 0)
                    count++;
  
                // Recursively Call DFS
                reorderPaths(Math.abs(graph[s][i]));
            }
        }
    }
  
    // Function to find minimum edges to
    // reverse to make the tree vertices
    // reachable for each node
    function minReorder(n)
    {
        // Stores the edges
        graph = [];
        for(let i = 0; i < n; i++)
        {
            graph.push([]);
        }
  
        // Traversing the childs
        for (let i = 0; i < edges.length; i++) {
            let a = edges[i][0];
            let b = edges[i][1];
  
            // Storing the direct edge
            graph[a].push(b);
  
            // Storing the reverse edge
            graph[b].push(-a);
        }
  
        // Finding ans for each node
        for (let i = 0; i < n; i++) {
            visited = new Array(n);
            visited.fill(false);
            count = 0;
  
            // Function Call
            reorderPaths(i);
            document.write(count + " ");
        }
    }
      
    let N = 6;
    edges = [ [ 0, 1 ], [ 1, 3 ], [ 2, 3 ], [ 4, 0 ], [ 4, 5 ] ];
    minReorder(N);
  
// This code is contributed by decode2207.
</script>


Output: 

2 2 2 3 1 2

 

Time Complexity: O(N2)
Auxiliary Space: O(N)



Similar Reads

Find the path from root to a vertex such that all K vertices belongs to this path or 1 distance away
Given a tree consisting of N vertices numbered from 1 to N rooted at vertex 1. You are given Q queries. Each query consists of the set of K distinct vertices vi[1], vi[2],…, vi[K]. The task is to determine if there is a path from the root to some vertex X such that each of the given K vertices either belongs to this path or has the distance 1 to so
10 min read
Check if incoming edges in a vertex of directed graph is equal to vertex itself or not
Given a directed Graph G(V, E) with V vertices and E edges, the task is to check that for all vertices of the given graph, the incoming edges in a vertex is equal to the vertex itself or not. Examples: Input: Output: Yes Explanation: For vertex 0 there are 0 incoming edges, for vertex 1 there is 1 incoming edge. Same for vertex 2 nd 3. Approach: Th
6 min read
Check if vertex X lies in subgraph of vertex Y for the given Graph
Given an undirected graph and two vertices X and Y, our task is to check whether the vertex X lies in the subgraph of the vertex Y. Examples: Input: X = 2, Y = 3 Output: No Explanation: Subgraph of a vertex Y = 3 is set of all the vertex which lies below Y and are reachable by Y. Here subgraph of 3 contains {6} not 2. Input: X = 6, Y = 1 Output: Ye
10 min read
Check if every vertex triplet in graph contains two vertices connected to third vertex
Given an undirected graph with N vertices and K edges, the task is to check if for every combination of three vertices in the graph, there exists two vertices which are connected to third vertex. In other words, for every vertex triplet (a, b, c), if there exists a path between a and c, then there should also exist a path between b and c. Examples:
9 min read
Find the vertex diagonally opposite to the vertex M from an N-sided polygon
Given two integers N and M, the task is to find the vertex diagonally opposite to the Mth vertex of an N-sided polygon. Examples: Input: N = 6, M = 2 Output: 5 Explanation: It can be observed from the image above that the vertex opposite to vertex 5 is 2. Input: N = 8, M = 5 Output: 1 Explanation: It can be observed from the image above that the ve
3 min read
Area of a triangle with two vertices at midpoints of opposite sides of a square and the other vertex lying on vertex of a square
Given a positive integer N representing the side of a square, the task is to find the area of a triangle formed by connecting the midpoints of two adjacent sides and vertex opposite to the two sides. Examples: Input: N = 10Output: 37.5 Input: N = 1Output: 0.375 Approach: The given problem can be solved based on the following observations: The one s
5 min read
Find vertex coordinates of all possible rectangles with a given vertex and dimensions
Given two integers L and B representing the length and breadth of a rectangle and a coordinate (X, Y) representing a point on the cartesian plane, the task is to find coordinates of all rectangles having a vertex as (X, Y) of the given dimensions. Example: Input: X=9, Y=9, L=5, B=3Output:(9, 9), (14, 9), (9, 12), (14, 12)(4, 9), (9, 9), (4, 12), (9
8 min read
Minimum cost path from source node to destination node via an intermediate node
Given an undirected weighted graph. The task is to find the minimum cost of the path from source node to the destination node via an intermediate node. Note: If an edge is traveled twice, only once weight is calculated as cost. Examples: Input: source = 0, destination = 2, intermediate = 3; Output: 6 The minimum cost path 0-&gt;1-&gt;3-&gt;1-&gt;2
12 min read
k'th heaviest adjacent node in a graph where each vertex has weight
Given a positive number k and an undirected graph of N nodes, numbered from 0 to N-1, each having a weight associated with it. Note that this is different from a normal weighted graph where every edge has a weight. For each node, if we sort the nodes (according to their weights), which are directly connected to it, in decreasing order, then what wi
7 min read
Largest subtree sum for each vertex of given N-ary Tree
Given an N-array tree of N nodes, rooted at 1, with edges in the form {u, v}, and an array values[] consisting of N integers. Each vertex i has an integer value denoted by values[i]. The task is to find the largest Subtree Sum possible for each vertex i by adding its value to a non-empty subset of its child vertices. Examples: Input: Edges[][] = {{
10 min read
Article Tags :
Practice Tags :