Skip to content
Related Articles

Related Articles

Find a Mother vertex in a Graph using Bit Masking

View Discussion
Improve Article
Save Article
  • Last Updated : 19 Jul, 2022

A mother vertex in a Graph G = (V, E) is a vertex v such that a path from v can reach all other vertices in G by a path from v. 
Example: 
 

Input: 
 

Output: 

 

 

Approach:
We can solve this problem using Depth First Search approach. To further optimize our approach, we will use an efficient solution. 
The below solution is also using Depth First Search to solve this problem, but it executes Depth First Search Cycle only once, and as soon as it finds the mother vertex, it stops the execution.
 

  • While executing the Depth First Search, we have a Bitmask Array representing a bitmask for each vertex. This Bitmask Array is passed to all vertices during execution.
  • Each vertex modifies their dedicated bitmask in such a way the all set bits representing the vertices can be visited from this vertex, including the current vertex.
  • At each iteration, we check if all the vertices can be visited from this vertex by checking the current vertex bitmask value (If bits representing to all vertices are set). If all vertices can be visited from this vertex, then it breaks the execution and finds the mother vertex as the current vertex.
  • If Vertex-2 has been visited from Vertex-1, and Vertex-2 has already been visited earlier, then the Vertex-1 updates it’s bitmask by doing OR operation with the Vertex-2 bitmask.

Time complexity: O(V+E)
How does the above idea work? 
Let this approach support a graph having a maximum of 32 vertices. This method can be augmented to support more number of vertices as well, but here it is dealt with a maximum of 32 vertices. 
 

  1. A bitmask array of 32 bit-masks is created. The 0th index of array denotes the Bitmask for Vertex-0, while the 1st index of the array denotes the Bitmask for Vertex-1, and so on. 
     
  2. All the vertices of the graph are visited using the Depth First Search algorithm, and the same bitmask array is passed to all vertices. The Bitmask values are set accordingly to represent all vertices that could be visited from this vertex.
  3. Bit Index is set corresponding to the neighbour vertices, including own bit index. Neighbour vertices will also repeat the same for their bitmask and return the same to Vertex-1.
  4. Vertex-1 will keep on performing the OR operation on the return value of all neighbours to its bitmask to represent all the vertices that could be visited from vertex-1.
  5. Do note that if the Vertex-2 is a neighbour of the Vertex-1, and it is already visited from another neighbour vertex, then it will not visit its neighbour’s vertex again and returns its bitmask to the first Node.
  6. Each iteration will check if bitmask corresponding to current vertex has all bits set to 1. If all bits are set to 1 for current vertex means, it means all vertices can be visited from the current vertex, and the current vertex is the mother vertex of the graph.

Below is the implementation of our above approach:
 

C++




#include<bits/stdc++.h>
using namespace std;
 
void PrintGraph(vector<vector<int>> adj)
{
    int n=(int)adj.size();
    for(int i=0;i<n;i++)
    {
        for(auto x:adj[i])
        {
            cout << "There is an edge from " << i <<" to " << x << '\n';
        }
    }
}
 
bool IsEdge(vector<vector<int>> adj,int src, int dest)
{
    for(auto x:adj[src])
    {
        if(x==dest)
            return true;
    }
    return false;
}
 
 
int MotherVertexUtil(
    vector<vector<int>> adj, int index,
    vector<int> mask, int* m_vertex)
{
    int n=(int)adj.size();
    // If mother vertex is already found
    // then simply return with existing
    // mask of the vertex index
    if (*m_vertex != -1) {
  
        return mask[index];
    }
  
    // if this vertex is already visited,
    // return the bit-mask
    // value of this vertex.
    if (mask[index] != 0) {
        return mask[index];
    }
  
    int tmpmask = 0;
  
    // Set the bit corresponding
    // to vertex index in tmpmask
    tmpmask |= (1 << index);
  
    for (int i = 0; i < n; i++) {
        if ((index != i)
            && IsEdge(adj, index, i)) {
  
            // Set bits corresponding to all
            // vertex which can be visited
            // by this vertex by ORing
            // the return value by util function
  
            // Vertex is not visited
            if (mask[i] == 0) {
  
                int retmask
                    = MotherVertexUtil(
                        adj, i, mask, m_vertex);
                tmpmask |= retmask;
            }
  
            // Vertex is already visited
            else {
                tmpmask |= mask[i];
            }
  
            // Check if current vertex is
            // mother vertex or mother vertex
            // is already found
            if (tmpmask == (pow(2, n) - 1)) {
  
                // If all bits of a mask is set
                // it means current vertex
                // is mother vertex
                if (*m_vertex == -1) {
                    *m_vertex = index;
                }
                return tmpmask;
            }
        }
    }
  
    // populate tmpmask as final
    // bit mask of the vertex
    mask[index] |= tmpmask;
  
    return mask[index];
}
  
 
int MotherVertex(vector<vector<int>> adj)
{
    int n=adj.size();
    vector<int> mask(n);
 
    // Initially bit mask
    // for all vertex will be 0
    for(int i=0;i<n;i++)
        mask[i]=0;
  
    // DFS traversal is used to check
    // for the mother vertex
    // All set bits (of bitmask of a vertex)
    // represent the current vertex index
    // and index of vertices which could be
    // visited from the current vertex.
  
    /* Example:
       If a vertex index is 3
       then and vertex 5, 7 and 10
       can be visited from this vertex
       then final bit mask of this vertex
       would be
       00000000000000000000010010101000
       (bits 3, 5, 7 and 10 are set) */
  
    // tmpmask is used to store
    // the final bitmask of the vertex.       
    int tmpmask = 0;
     
    // flag to check if
    // mother vertex is found
    int m_vertex = -1;
 
   for (int index = 0; index < n; index++) {
  
        // set the bit corresponding
        // to vertex index in tmpmask
        tmpmask = (1 << index);
  
        // mask for a vertex is 0
        // means it has not yet
        // visited so visit this vertex
        if (mask[index] == 0) {
  
            int retmask= MotherVertexUtil(adj, index,mask, &m_vertex);
  
            // set bits corresponding to all
            // vertices which can be visited
            // from this vertex by ORing
            // the return value by util function
            tmpmask |= retmask;
        }
  
        // check if current vertex is
        // mother vertex or mother vertex
        // is already found
        // If all bits of a mask is set
        // it means current vertex
        // is mother vertex
        if (tmpmask == (pow(2, n) - 1)) {
  
            // current vertex is mother vertex
            if (m_vertex == -1) {
                m_vertex = index;
            }
            break;
        }
  
        // populate tmpmask as final bit
        // mask of the vertex
        mask[index] |= tmpmask;
    }
  
    return m_vertex;
}
 
int main()
{
    int n;
    n = 7;
    vector<vector<int>> adj(n);
    adj[0].push_back(2);
    adj[0].push_back(1);
    adj[1].push_back(3);
    adj[4].push_back(1);
    adj[5].push_back(2);
    adj[5].push_back(6);
    adj[6].push_back(0);
    adj[6].push_back(4);
    PrintGraph(adj);
 
    int m_vertex = MotherVertex(adj);
    if( m_vertex == -1)
    {
        cout << "Mother vertex is not existing in this graph\n";
    }
    else
    {
        cout << "Mother vertex is: " << m_vertex << '\n';
    }
    return 0;
}

Java




// Java code for above implementation
import java.util.*;
 
public class Main {
  public static void main(String[] args)
  {
    int n = 7;
    ArrayList<ArrayList<Integer> > adj
      = new ArrayList<>();
    for (int i = 0; i < n; i++) {
      adj.add(new ArrayList<>());
    }
    adj.get(0).add(2);
    adj.get(0).add(1);
    adj.get(1).add(3);
    adj.get(4).add(1);
    adj.get(5).add(2);
    adj.get(5).add(6);
    adj.get(6).add(0);
    adj.get(6).add(4);
    PrintGraph(adj);
 
    int m_vertex = MotherVertex(adj);
    if (m_vertex == -1) {
      System.out.println(
        "Mother vertex is not existing in this graph");
    }
    else {
      System.out.println("Mother vertex is: "
                         + m_vertex);
    }
  }
 
  public static void
    PrintGraph(ArrayList<ArrayList<Integer> > adj)
  {
    int n = adj.size();
    for (int i = 0; i < n; i++) {
      for (int x : adj.get(i)) {
        System.out.println("There is an edge from "
                           + i + " to " + x);
      }
    }
  }
 
  public static boolean
    IsEdge(ArrayList<ArrayList<Integer> > adj, int src,
           int dest)
  {
    for (int x : adj.get(src)) {
      if (x == dest)
        return true;
    }
    return false;
  }
 
  public static int
    MotherVertexUtil(ArrayList<ArrayList<Integer> > adj,
                     int index, int[] mask, int m_vertex)
  {
    int n = adj.size();
 
    // If mother vertex is already found
    // then simply return with existing
    // mask of the vertex index
    if (m_vertex != -1) {
      return mask[index];
    }
 
    // if this vertex is already visited,
    // return the bit-mask
    // value of this vertex.
    if (mask[index] != 0) {
      return mask[index];
    }
 
    int tmpmask = 0;
 
    // Set the bit corresponding
    // to vertex index in tmpmask
    tmpmask |= (1 << index);
 
    for (int i = 0; i < n; i++) {
      if ((index != i) && IsEdge(adj, index, i)) {
 
        // Set bits corresponding to all
        // vertex which can be visited
        // by this vertex by ORing
        // the return value by util function
 
        // Vertex is not visited
        if (mask[i] == 0) {
 
          int retmask = MotherVertexUtil(
            adj, i, mask, m_vertex);
          tmpmask |= retmask;
        }
 
        // Vertex is already visited
        else {
          tmpmask |= mask[i];
        }
 
        // Check if current vertex is
        // mother vertex or mother vertex
        // is already found
        if (tmpmask == (Math.pow(2, n) - 1)) {
 
          // If all bits of a mask is set
          // it means current vertex
          // is mother vertex
          if (m_vertex == -1) {
            m_vertex = index;
          }
 
          return tmpmask;
        }
      }
    }
 
    // populate tmpmask as final
    // bit mask of the vertex
    mask[index] |= tmpmask;
 
    return mask[index];
  }
 
  public static int
    MotherVertex(ArrayList<ArrayList<Integer> > adj)
  {
    int n = adj.size();
    int[] mask = new int[n];
 
    // Initially bit mask
    // for all vertex will be 0
    for (int i = 0; i < n; i++)
      mask[i] = 0;
 
    // DFS traversal is used to check
    // for the mother vertex
    // All set bits (of bitmask of a vertex)
    // represent the current vertex index
    // and index of vertices which could be
    // visited from the current vertex.
 
    /* Example:
           If a vertex index is 3
           then and vertex 5, 7 and 10
           can be visited from this vertex
           then final bit mask of this vertex
           would be
           00000000000000000000010010101000
           (bits 3, 5, 7 and 10 are set) */
 
    // tmpmask is used to store
    // the final bitmask of the vertex.
    int tmpmask = 0;
 
    // flag to check if
    // mother vertex is found
    int m_vertex = -1;
 
    for (int index = 0; index < n; index++) {
 
      // set the bit corresponding
      // to vertex index in tmpmask
      tmpmask = (1 << index);
 
      // mask for a vertex is 0
      // means it has not yet
      // visited so visit this vertex
      if (mask[index] == 0) {
        int retmask = MotherVertexUtil(
          adj, index, mask, m_vertex);
 
        // set bits corresponding to all
        // vertices which can be visited
        // from this vertex by ORing
        // the return value by util function
        tmpmask |= retmask;
      }
 
      // check if current vertex is
      // mother vertex or mother vertex
      // is already found
      // If all bits of a mask is set
      // it means current vertex
      // is mother vertex
      if (tmpmask == (Math.pow(2, n) - 1)) {
        // current vertex is mother vertex
        if (m_vertex == -1) {
          m_vertex = index;
        }
        break;
      }
      // populate tmpmask as final bit
      // mask of the vertex
      mask[index] |= tmpmask;
    }
    return m_vertex;
  }
}
 
// This code is contributed by Tapesh (tapeshdua420)

Python3




def PrintGraph(adj):
    n = len(adj)
    for i in range(n):
        for x in adj[i]:
            print("There is an edge from {} to {}".format(i, x))
 
 
def IsEdge(adj, src, dest):
    for x in adj[src]:
        if(x == dest):
            return True
 
    return False
 
 
def MotherVertexUtil(adj, index, mask, m_vertex):
    n = len(adj)
    # If mother vertex is already found
    # then simply return with existing
    # mask of the vertex index
    if (m_vertex[0] != -1):
 
        return mask[index]
 
    # if this vertex is already visited,
    # return the bit-mask
    # value of this vertex.
    if (mask[index] != 0):
        return mask[index]
 
    tmpmask = 0
 
    # Set the bit corresponding
    # to vertex index in tmpmask
    tmpmask |= (1 << index)
 
    for i in range(n):
        if ((index != i) and IsEdge(adj, index, i)):
 
            # Set bits corresponding to all
            # vertex which can be visite
            # by this vertex by ORing
            # the return value by util function
 
            # Vertex is not visited
            if (mask[i] == 0):
 
                retmask = MotherVertexUtil(adj, i, mask, m_vertex)
                tmpmask |= retmask
 
            # Vertex is already visited
            else:
                tmpmask |= mask[i]
 
            # Check if current vertex is
            # mother vertex or mother vertex
            # is already found
            if (tmpmask == (pow(2, n) - 1)):
 
                # If all bits of a mask is set
                # it means current vertex
                # is mother vertex
                if (m_vertex[0] == -1):
                    m_vertex[0] = index
 
                return tmpmask
 
    # populate tmpmask as final
    # bit mask of the vertex
    mask[index] |= tmpmask
 
    return mask[index]
 
 
def MotherVertex(adj):
    n = len(adj)
    mask = [0]*n
 
    # Initially bit mask
    # for all vertex will be 0
    for i in range(n):
        mask[i] = 0
 
    # DFS traversal is used to check
    # for the mother vertex
    # All set bits (of bitmask of a vertex)
    # represent the current vertex index
    # and index of vertices which could be
    # visited from the current vertex.
 
    # Example:
    #    If a vertex index is 3
    #    then and vertex 5, 7 and 10
    #    can be visited from this vertex
    #    then final bit mask of this vertex
    #    would be
    #    00000000000000000000010010101000
    #    (bits 3, 5, 7 and 10 are set)
 
    # tmpmask is used to store
    # the final bitmask of the vertex.
    tmpmask = 0
 
    # flag to check if
    # mother vertex is found
    m_vertex = [-1, ]
 
    for index in range(n):
 
        # set the bit corresponding
        # to vertex index in tmpmask
        tmpmask = (1 << index)
 
        # mask for a vertex is 0
        # means it has not yet
        # visited so visit this vertex
        if (mask[index] == 0):
 
            retmask = MotherVertexUtil(adj, index, mask, m_vertex)
 
            # set bits corresponding to all
            # vertices which can be visited
            # from this vertex by ORing
            # the return value by util function
            tmpmask |= retmask
 
        # check if current vertex is
        # mother vertex or mother vertex
        # is already found
        # If all bits of a mask is set
        # it means current vertex
        # is mother vertex
        if (tmpmask == (pow(2, n) - 1)):
 
            # current vertex is mother vertex
            if (m_vertex[0] == -1):
                m_vertex[0] = index
 
            break
 
        # populate tmpmask as final bit
        # mask of the vertex
        mask[index] |= tmpmask
 
    return m_vertex[0]
 
 
if __name__ == '__main__':
    n = 7
    adj = [[] for _ in range(n)]
    adj[0].append(2)
    adj[0].append(1)
    adj[1].append(3)
    adj[4].append(1)
    adj[5].append(2)
    adj[5].append(6)
    adj[6].append(0)
    adj[6].append(4)
    PrintGraph(adj)
 
    m_vertex = MotherVertex(adj)
    if(m_vertex == -1):
        print("Mother vertex is not existing in this graph")
 
    else:
        print("Mother vertex is:", m_vertex)

C#




// C# code for above implementation
using System;
using System.Collections.Generic;
using System.Linq;
 
class Program {
  public static void Main(string[] args)
  {
 
    int n = 7;
    List<List<int> > adj = new List<List<int> >();
    for (int i = 0; i < n; i++) {
      adj.Add(new List<int>());
    }
 
    adj[0].Add(2);
    adj[0].Add(1);
    adj[1].Add(3);
    adj[4].Add(1);
    adj[5].Add(2);
    adj[5].Add(6);
    adj[6].Add(0);
    adj[6].Add(4);
    PrintGraph(adj);
 
    int m_vertex = MotherVertex(adj);
    if (m_vertex == -1) {
      Console.WriteLine(
        "Mother vertex is not existing in this graph");
    }
    else {
      Console.WriteLine("Mother vertex is: "
                        + m_vertex);
    }
  }
 
  public static void PrintGraph(List<List<int> > adj)
  {
    int n = adj.Count();
    for (int i = 0; i < n; i++) {
      foreach(var x in adj[i])
      {
        Console.WriteLine("There is an edge from "
                          + i + " to " + x);
      }
    }
  }
 
  public static bool IsEdge(List<List<int> > adj, int src,
                            int dest)
  {
    foreach(var x in adj[src])
    {
      if (x == dest)
        return true;
    }
    return false;
  }
  public static int MotherVertexUtil(List<List<int> > adj,
                                     int index,
                                     int[] mask,
                                     int m_vertex)
  {
    int n = adj.Count();
 
    // If mother vertex is already found
    // then simply return with existing
    // mask of the vertex index
    if (m_vertex != -1)
      return mask[index];
 
    // if this vertex is already visited,
    // return the bit-mask
    // value of this vertex.
    if (mask[index] != 0)
      return mask[index];
 
    int tmpmask = 0;
 
    // Set the bit corresponding
    // to vertex index in tmpmask
    tmpmask |= (1 << index);
 
    for (int i = 0; i < n; i++) {
      if ((index != i) && IsEdge(adj, index, i)) {
 
        // Set bits corresponding to all
        // vertex which can be visited
        // by this vertex by ORing
        // the return value by util function
 
        // Vertex is not visited
        if (mask[i] == 0) {
          int retmask = MotherVertexUtil(
            adj, i, mask, m_vertex);
          tmpmask |= retmask;
        }
 
        // Vertex is already visited
        else {
          tmpmask |= mask[i];
        }
 
        // Check if current vertex is
        // mother vertex or mother vertex
        // is already found
        if (tmpmask == Math.Pow((2), n) - 1) {
          // If all bits of a mask is set
          // it means current vertex
          // is mother vertex
          if (m_vertex == -1) {
            m_vertex = index;
          }
 
          return tmpmask;
        }
      }
    }
 
    // populate tmpmask as final
    // bit mask of the vertex
    mask[index] |= tmpmask;
 
    return mask[index];
  }
  public static int MotherVertex(List<List<int> > adj)
  {
    int n = adj.Count();
    int[] mask = new int[n];
 
    // Initially bit mask
    // for all vertex will be 0
    for (int i = 0; i < n; i++) {
      mask[i] = 0;
    }
 
    // DFS traversal is used to check
    // for the mother vertex
    // All set bits (of bitmask of a vertex)
    // represent the current vertex index
    // and index of vertices which could be
    // visited from the current vertex.
 
    /* Example:
               If a vertex index is 3
               then and vertex 5, 7 and 10
               can be visited from this vertex
               then final bit mask of this vertex
               would be
               00000000000000000000010010101000
               (bits 3, 5, 7 and 10 are set) */
 
    // tmpmask is used to store
    // the final bitmask of the vertex.
    int tmpmask = 0;
 
    // flag to check if
    // mother vertex is found
    int m_vertex = -1;
    for (int index = 0; index < n; index++) {
 
      // set the bit corresponding
      // to vertex index in tmpmask
      tmpmask = 1 << index;
 
      // mask for a vertex is 0
      // means it has not yet
      // visited so visit this vertex
      if (mask[index] == 0) {
        int retmask = MotherVertexUtil(
          adj, index, mask, m_vertex);
 
        // set bits corresponding to all
        // vertices which can be visited
        // from this vertex by ORing
        // the return value by util function
        tmpmask |= retmask;
      }
 
      // check if current vertex is
      // mother vertex or mother vertex
      // is already found
      // If all bits of a mask is set
      // it means current vertex
      // is mother vertex
      if (tmpmask == Math.Pow((2), n) - 1)
      {
         
        // current vertex is mother vertex
        if (m_vertex == -1) {
          m_vertex = index;
        }
        break;
      }
       
      // populate tmpmask as final bit
      // mask of the vertex
      mask[index] |= tmpmask;
    }
    return m_vertex;
  }
}
 
// This code is contributed by Tapesh (tapeshdua420)

Output

There is an edge from 0 to 2
There is an edge from 0 to 1
There is an edge from 1 to 3
There is an edge from 4 to 1
There is an edge from 5 to 2
There is an edge from 5 to 6
There is an edge from 6 to 0
There is an edge from 6 to 4
Mother vertex is: 5

Time Complexity: O(V ^ 2), where V is the total number of vertices in the graph.
Auxiliary Space: O(V) 


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!