Given an undirected graph of N vertices and M edges, the task is to assign directions to the given M Edges such that the graph becomes Strongly Connected Components. If a graph cannot be converted into Strongly Connected Components then print “-1”.
Examples:
Input: N = 5, Edges[][] = { { 0, 1 }, { 0, 2 }, { 1, 2 }, { 1, 4 }, { 2, 3 }, { 3, 4 } }
Output:
0->1
2->0
4->1
3->4
2->3
1->2
Explanation:
Below is the assigned edges to the above undirected graph:
Input: N = 5, Edges[][] = { { 0, 1 }, { 0, 2 }, { 1, 3 }, { 2, 3 }, { 3, 4 } }
Output: -1
Explanation:
Below is the graph for the above information:
Since there is a bridge present in the above-undirected graph. Therefore, this graph can’t be converted into SCCs.
Approach: We know that in any directed graph is said to be in Strongly Connected Components(SCCs) if all the vertices of the graph are a part of some cycle. The given undirected graph doesn’t form SCCs if and only if the graph contains any bridges in it. Below are the steps:
- We will use an array mark[] to store the visited node during DFS Traversal, order[] to store the index number of the visited node, and bridge_detect[] to store any bridge present in the given graph.
 - Start the DFS Traversal from vertex 1.
 - Traverse the Adjacency list of current Node and do the following: 
- If any edges are traverse again while any DFS call then ignore that edges.
 - If the order of child Node(Node u) is greater than the order of parent node(node v), then ignore this current edges as Edges(v, u) is already processed.
 - If any Back Edge is found then update the Bridge Edges of the current parent node(node v) as:
 
 
bridge_detect[v] = min(order[u], bridge_detect[v]);
- Else do the DFS Traversal for the current child node and repeat step 3 for the current node.
 - Update the bridges detect after DFS call for the current node as:
 
bridge_detect[v] = min(bridge_detect[u], bridge_detect[v])
- Store the current pair of Edges(v, u) as directed Edges from Node v to Node u in an array of pairs(say arr[][]).
 - If there is any bridge present in the given graph then print “-1”.
 - Else print the directed Edges stored in arr[][].
 
Below is the implementation of the above approach:
C++
// C++ program for the above approach#include <bits/stdc++.h>using namespace std;// To store the assigned Edgesvector<pair<int, int> > ans;// Flag variable to check Bridgesint flag = 1;// Function to implement DFS Traversalint dfs(vector<int> adj[],        int* order, int* bridge_detect,        bool* mark, int v, int l){    // Mark the current node as visited    mark[v] = 1;    // Update the order of node v    order[v] = order[l] + 1;    // Update the bridge_detect for node v    bridge_detect[v] = order[v];    // Traverse the adjacency list of    // Node v    for (int i = 0; i < adj[v].size(); i++) {        int u = adj[v][i];        // Ignores if same edge is traversed        if (u == l) {            continue;        }        // Ignores the edge u --> v as        // v --> u is already processed        if (order[v] < order[u]) {            continue;        }        // Finds a back Edges, cycle present        if (mark[u]) {            // Update the bridge_detect[v]            bridge_detect[v]                = min(order[u],                      bridge_detect[v]);        }        // Else DFS traversal for current        // node in the adjacency list        else {            dfs(adj, order, bridge_detect,                mark, u, v);        }        // Update the bridge_detect[v]        bridge_detect[v]            = min(bridge_detect[u],                  bridge_detect[v]);        // Store the current directed Edge        ans.push_back(make_pair(v, u));    }    // Condition for Bridges    if (bridge_detect[v] == order[v]        && l != 0) {        flag = 0;    }    // Return flag    return flag;}// Function to print the direction// of edges to make graph SCCsvoid convert(vector<int> adj[], int n){    // Arrays to store the visited,    // bridge_detect and order of    // Nodes    int order[n] = { 0 };    int bridge_detect[n] = { 0 };    bool mark[n];    // Initialise marks[] as false    memset(mark, false, sizeof(mark));    // DFS Traversal from vertex 1    int flag = dfs(adj, order,                   bridge_detect,                   mark, 1, 0);    // If flag is zero, then Bridge    // is present in the graph    if (flag == 0) {        cout << "-1";    }    // Else print the direction of    // Edges assigned    else {        for (auto& it : ans) {            cout << it.first << "->"                 << it.second << '\n';        }    }}// Function to create graphvoid createGraph(int Edges[][2],                 vector<int> adj[],                 int M){    // Traverse the Edges    for (int i = 0; i < M; i++) {        int u = Edges[i][0];        int v = Edges[i][1];        // Push the edges in an        // adjacency list        adj[u].push_back(v);        adj[v].push_back(u);    }}// Driver Codeint main(){    // N vertices and M Edges    int N = 5, M = 6;    int Edges[M][2]        = { { 0, 1 }, { 0, 2 },            { 1, 2 }, { 1, 4 },            { 2, 3 }, { 3, 4 } };    // To create Adjacency List    vector<int> adj[N];    // Create an undirected graph    createGraph(Edges, adj, M);    // Function Call    convert(adj, N);    return 0;} | 
Java
// Java program for the above approachimport java.util.*;import java.lang.*;class GFG{     // To store the assigned Edgesstatic ArrayList<int[]> ans;  // Flag variable to check Bridgesstatic int flag = 1;  // Function to implement DFS Traversalstatic int dfs(ArrayList<ArrayList<Integer>> adj,               int[] order, int[] bridge_detect,               boolean[] mark, int v, int l){         // Mark the current node as visited    mark[v] = true;         // Update the order of node v    order[v] = order[l] + 1;      // Update the bridge_detect for node v    bridge_detect[v] = order[v];      // Traverse the adjacency list of    // Node v    for(int i = 0; i < adj.get(v).size(); i++)    {        int u = adj.get(v).get(i);          // Ignores if same edge is traversed        if (u == l)        {            continue;        }          // Ignores the edge u --> v as        // v --> u is already processed        if (order[v] < order[u])        {            continue;        }          // Finds a back Edges, cycle present        if (mark[u])         {                         // Update the bridge_detect[v]            bridge_detect[v] = Math.min(order[u],                                bridge_detect[v]);        }          // Else DFS traversal for current        // node in the adjacency list        else        {            dfs(adj, order, bridge_detect,                mark, u, v);        }          // Update the bridge_detect[v]        bridge_detect[v] = Math.min(bridge_detect[u],                                    bridge_detect[v]);          // Store the current directed Edge        ans.add(new int[]{v, u});    }      // Condition for Bridges    if (bridge_detect[v] == order[v] && l != 0)    {        flag = 0;    }         // Return flag    return flag;}  // Function to print the direction// of edges to make graph SCCsstatic void convert(ArrayList<ArrayList<Integer>> adj,                     int n){         // Arrays to store the visited,    // bridge_detect and order of    // Nodes    int[] order = new int[n];    int[] bridge_detect = new int[n];    boolean mark[] = new boolean[n];         // DFS Traversal from vertex 1    int flag = dfs(adj, order,                   bridge_detect,                   mark, 1, 0);      // If flag is zero, then Bridge    // is present in the graph    if (flag == 0)     {        System.out.print("-1");    }      // Else print the direction of    // Edges assigned    else    {        for(int[] it : ans)        {            System.out.println(it[0] + "->" +                                it[1]);        }    }}  // Function to create graphstatic void createGraph(int Edges[][],                        ArrayList<ArrayList<Integer>> adj,                        int M){         // Traverse the Edges    for(int i = 0; i < M; i++)     {        int u = Edges[i][0];        int v = Edges[i][1];                 // Push the edges in an        // adjacency list        adj.get(u).add(v);        adj.get(v).add(u);    }}// Driver codepublic static void main(String[] args){         // N vertices and M Edges    int N = 5, M = 6;         int Edges[][] = { { 0, 1 }, { 0, 2 },                      { 1, 2 }, { 1, 4 },                      { 2, 3 }, { 3, 4 } };         // To create Adjacency List    ArrayList<ArrayList<Integer>> adj = new ArrayList<>();    ans = new ArrayList<>();         for(int i = 0; i < N; i++)        adj.add(new ArrayList<>());         // Create an undirected graph    createGraph(Edges, adj, M);         // Function Call    convert(adj, N);}}// This code is contributed by offbeat | 
Python3
# Python3 program for # the above approach# To store the assigned # Edgesans = []  # Flag variable to # check Bridgesflag = 1;  # Function to implement # DFS Traversaldef dfs(adj, order,         bridge_detect,         mark, v, l):         global flag         # Mark the current     # node as visited    mark[v] = 1;      # Update the order of     # node v    order[v] = order[l] + 1;      # Update the bridge_detect     # for node v    bridge_detect[v] = order[v];      # Traverse the adjacency list of    # Node v    for i in range(len(adj[v])):                u = adj[v][i];          # Ignores if same edge         # is traversed        if (u == l):            continue;                 # Ignores the edge u --> v as        # v --> u is already processed        if (order[v] < order[u]):            continue;                  # Finds a back Edges,         # cycle present        if (mark[u]):              # Update the bridge_detect[v]            bridge_detect[v] = min(order[u],                                  bridge_detect[v]);                 # Else DFS traversal for current        # node in the adjacency list        else:              dfs(adj, order,                 bridge_detect,                mark, u, v);                  # Update the bridge_detect[v]        bridge_detect[v] = min(bridge_detect[u],                              bridge_detect[v]);          # Store the current         # directed Edge        ans.append([v, u]);      # Condition for Bridges    if (bridge_detect[v] ==        order[v] and l != 0):        flag = 0;         # Return flag    return flag;  # Function to print the # direction of edges to # make graph SCCsdef convert(adj, n):      # Arrays to store the visited,    # bridge_detect and order of    # Nodes    order = [0 for i in range(n)]    bridge_detect = [0 for i in range(n)]    mark = [False for i in range(n)]      # DFS Traversal from     # vertex 1    flag = dfs(adj, order,               bridge_detect,               mark, 1, 0);      # If flag is zero, then Bridge    # is present in the graph    if (flag == 0):        print(-1)      # Else print the direction     # of Edges assigned    else:        for it in ans:            print("{} -> {}".format(it[0],                                    it[1]))# Function to create graphdef createGraph(Edges,adj, M):      # Traverse the Edges    for i in range(M):          u = Edges[i][0];        v = Edges[i][1];          # Push the edges in an        # adjacency list        adj[u].append(v);        adj[v].append(u);# Driver codeif __name__ == "__main__":         # N vertices and M Edges    N = 5    M = 6;    Edges = [[0, 1], [0, 2],            [1, 2], [1, 4],            [2, 3], [3, 4]];      # To create Adjacency List    adj = [[] for i in range(N)]      # Create an undirected graph    createGraph(Edges, adj, M);      # Function Call    convert(adj, N);# This code is contributed by rutvik_56 | 
C#
// C# program for the above approachusing System;using System.Collections;using System.Collections.Generic;  class GFG{      // To store the assigned Edgesstatic ArrayList ans;   // Flag variable to check Bridgesstatic int flag = 1;   // Function to implement DFS Traversalstatic int dfs(ArrayList adj,               int[] order, int[] bridge_detect,               bool[] mark, int v, int l){         // Mark the current node as visited    mark[v] = true;         // Update the order of node v    order[v] = order[l] + 1;         // Update the bridge_detect for node v    bridge_detect[v] = order[v];       // Traverse the adjacency list of    // Node v    for(int i = 0;             i < ((ArrayList)adj[v]).Count;             i++)    {        int u = (int)((ArrayList)adj[v])[i];                 // Ignores if same edge is traversed        if (u == l)        {            continue;        }                 // Ignores the edge u --> v as        // v --> u is already processed        if (order[v] < order[u])        {            continue;        }                 // Finds a back Edges, cycle present        if (mark[u])         {                         // Update the bridge_detect[v]            bridge_detect[v] = Math.Min(order[u],                                bridge_detect[v]);        }                 // Else DFS traversal for current        // node in the adjacency list        else        {            dfs(adj, order, bridge_detect,                mark, u, v);        }           // Update the bridge_detect[v]        bridge_detect[v] = Math.Min(bridge_detect[u],                                    bridge_detect[v]);           // Store the current directed Edge        ans.Add(new int[]{v, u});    }       // Condition for Bridges    if (bridge_detect[v] == order[v] && l != 0)    {        flag = 0;    }         // Return flag    return flag;}   // Function to print the direction// of edges to make graph SCCsstatic void convert(ArrayList adj,                     int n){         // Arrays to store the visited,    // bridge_detect and order of    // Nodes    int[] order = new int[n];    int[] bridge_detect = new int[n];    bool []mark = new bool[n];         // DFS Traversal from vertex 1    int flag = dfs(adj, order,                   bridge_detect,                   mark, 1, 0);                        // If flag is zero, then Bridge    // is present in the graph    if (flag == 0)     {        Console.Write("-1");    }         // Else print the direction of    // Edges assigned    else    {        foreach(int[] it in ans)        {            Console.WriteLine(it[0] + "->" +                               it[1]);        }    }}   // Function to create graphstatic void createGraph(int [,]Edges,                        ArrayList adj,                        int M){         // Traverse the Edges    for(int i = 0; i < M; i++)     {        int u = Edges[i, 0];        int v = Edges[i, 1];                 // Push the edges in an        // adjacency list        ((ArrayList)adj[u]).Add(v);        ((ArrayList)adj[v]).Add(u);    }}  // Driver codepublic static void Main(string[] args){         // N vertices and M Edges    int N = 5, M = 6;          int [,]Edges = { { 0, 1 }, { 0, 2 },                     { 1, 2 }, { 1, 4 },                     { 2, 3 }, { 3, 4 } };          // To create Adjacency List    ArrayList adj = new ArrayList();    ans = new ArrayList();          for(int i = 0; i < N; i++)        adj.Add(new ArrayList());          // Create an undirected graph    createGraph(Edges, adj, M);          // Function Call    convert(adj, N);}}// This code is contributed by pratham76 | 
Javascript
<script>    // Javascript program for the above approach         // To store the assigned Edges    let ans;    // Flag variable to check Bridges    let flag = 1;    // Function to implement DFS Traversal    function dfs(adj, order, bridge_detect, mark, v, l)    {        // Mark the current node as visited        mark[v] = true;        // Update the order of node v        order[v] = order[l] + 1;        // Update the bridge_detect for node v        bridge_detect[v] = order[v];        // Traverse the adjacency list of        // Node v        for(let i = 0; i < adj[v].length; i++)        {            let u = adj[v][i];            // Ignores if same edge is traversed            if (u == l)            {                continue;            }            // Ignores the edge u --> v as            // v --> u is already processed            if (order[v] < order[u])            {                continue;            }            // Finds a back Edges, cycle present            if (mark[u])            {                // Update the bridge_detect[v]                bridge_detect[v] = Math.min(order[u],                                    bridge_detect[v]);            }            // Else DFS traversal for current            // node in the adjacency list            else            {                dfs(adj, order, bridge_detect, mark, u, v);            }            // Update the bridge_detect[v]            bridge_detect[v] = Math.min(bridge_detect[u], bridge_detect[v]);            // Store the current directed Edge            ans.push([v, u]);        }        // Condition for Bridges        if (bridge_detect[v] == order[v] && l != 0)        {            flag = 0;        }        // Return flag        return flag;    }    // Function to print the direction    // of edges to make graph SCCs    function convert(adj, n)    {        // Arrays to store the visited,        // bridge_detect and order of        // Nodes        let order = new Array(n);        let bridge_detect = new Array(n);        let mark = new Array(n);        // DFS Traversal from vertex 1        let flag = dfs(adj, order, bridge_detect, mark, 1, 0);        // If flag is zero, then Bridge        // is present in the graph        if (flag == 0)        {            document.write("-1");        }        // Else print the direction of        // Edges assigned        else        {            for(let it = 0; it < ans.length - 1; it++)            {                document.write(ans[it][0] + "->" + ans[it][1] + "</br>");            }        }    }    // Function to create graph    function createGraph(Edges, adj, M)    {        // Traverse the Edges        for(let i = 0; i < M; i++)        {            let u = Edges[i][0];            let v = Edges[i][1];            // Push the edges in an            // adjacency list            adj[u].push(v);            adj[v].push(u);        }    }         // N vertices and M Edges    let N = 5, M = 6;           let Edges = [ [ 0, 1 ], [ 0, 2 ],                     [ 1, 2 ], [ 1, 4 ],                     [ 2, 3 ], [ 3, 4 ] ];           // To create Adjacency List    let adj = [];    ans = [];           for(let i = 0; i < N; i++)        adj.push([]);           // Create an undirected graph    createGraph(Edges, adj, M);           // Function Call    convert(adj, N);// This code is contributed by suresh07.</script> | 
0->1 2->0 4->1 3->4 2->3 1->2
Time Complexity: O(N)
Auxiliary Space: O(N)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

                                    