Mother Vertex in a Graph (original) (raw)

Given a **directed graph with **V vertices labeled from 0 to V-1 and a list of edges **edges[][], where each edge is represented as [u, v] indicating a directed edge from vertex u to vertex v, find a **Mother Vertex of the graph.

A Mother Vertex is a vertex from which all other vertices can be reached.

**Example:

Mother-Vertex-in-a-Graph

**Input: V = 7, edges[][] = [[0, 1], [0, 2], [1, 3], [4, 1], [6, 4], [5, 6], [5, 2], [6, 0]]
**Output: 5
**Explanation: As shown in the above graph.

**Input: V = 5, edges[][] = [[0, 2], [0, 3], [1, 0], [2, 1], [3, 4]]
**Output: 0
**Explanation: Vertices 0, 1, and 2 can each reach all other vertices in the graph. Among them, 0 is the smallest, so the output is 0.

Table of Content

[Naive Approach] - Using BFS(Breadth First Search) - O(V * (E + V)) Time and O(V) Space

A straightforward (brute-force) approach is to run BFS (or DFS) from every vertex and check whether all other vertices are reachable from it. If such a vertex exists, it is a mother vertex. However, this approach is inefficient, as it requires performing a traversal for each vertex.

C++ `

#include <bits/stdc++.h> using namespace std;

// BFS traversal starting from a vertex void bfsFromVertex(int v, vector &visited, vector<vector> &adj) { queue q;

// Mark starting vertex visited
visited[v] = true;
q.push(v);

while (!q.empty())
{
    int node = q.front();
    q.pop();

    for (int neighbor : adj[node])
    {
        if (!visited[neighbor])
        {
            visited[neighbor] = true;
            q.push(neighbor);
        }
    }
}

}

// Function to find a mother vertex using BFS int findMotherVertex(int V, vector<vector> &edges) { // Adjacency list vector<vector> adj(V); for (auto &edge : edges) { adj[edge[0]].push_back(edge[1]); }

// Try BFS from every vertex
for (int i = 0; i < V; i++)
{
    vector<bool> visited(V, false);

    bfsFromVertex(i, visited, adj);

    // Check if all nodes are visited
    bool allVisited = true;
    for (bool v : visited)
    {
        if (!v)
        {
            allVisited = false;
            break;
        }
    }

    if (allVisited)
        return i;
}

return -1;

}

int main() { int V = 7;

vector<vector<int>> edges = {{0, 1}, {0, 2}, {1, 3}, {4, 1}, {6, 4}, {5, 6}, {5, 2}, {6, 0}};

cout << findMotherVertex(V, edges) << endl;

return 0;

}

Java

import java.util.*;

public class GFG {

// BFS traversal starting from a vertex
static void bfsFromVertex(int v, boolean[] visited,
                          List<List<Integer> > adj)
{

    Queue<Integer> q = new LinkedList<>();

    // Mark starting vertex visited
    visited[v] = true;
    q.add(v);

    while (!q.isEmpty()) {
        int node = q.poll();

        for (int neighbor : adj.get(node)) {
            if (!visited[neighbor]) {
                visited[neighbor] = true;
                q.add(neighbor);
            }
        }
    }
}

// Function to find a mother vertex using BFS
static int findMotherVertex(int V, int[][] edges)
{

    // Adjacency list
    List<List<Integer> > adj = new ArrayList<>();
    for (int i = 0; i < V; i++) {
        adj.add(new ArrayList<>());
    }

    for (int[] edge : edges) {
        adj.get(edge[0]).add(edge[1]);
    }

    // Try BFS from every vertex
    for (int i = 0; i < V; i++) {

        boolean[] visited = new boolean[V];

        bfsFromVertex(i, visited, adj);

        // Check if all nodes are visited
        boolean allVisited = true;
        for (boolean v : visited) {
            if (!v) {
                allVisited = false;
                break;
            }
        }

        if (allVisited)
            return i;
    }

    return -1;
}

public static void main(String[] args)
{

    int V = 7;

    int[][] edges
        = { { 0, 1 }, { 0, 2 }, { 1, 3 }, { 4, 1 },
            { 6, 4 }, { 5, 6 }, { 5, 2 }, { 6, 0 } };

    System.out.println(findMotherVertex(V, edges));
}

}

Python

from collections import deque

BFS traversal starting from a vertex

def bfsFromVertex(v, visited, adj):

q = deque()

# Mark starting vertex visited
visited[v] = True
q.append(v)

while q:
    node = q.popleft()

    for neighbor in adj[node]:
        if not visited[neighbor]:
            visited[neighbor] = True
            q.append(neighbor)

Function to find a mother vertex using BFS

def findMotherVertex(V, edges):

# Adjacency list
adj = [[] for _ in range(V)]

for u, v in edges:
    adj[u].append(v)

# Try BFS from every vertex
for i in range(V):

    visited = [False] * V

    bfsFromVertex(i, visited, adj)

    # Check if all nodes are visited
    if all(visited):
        return i

return -1

Driver code

if name == "main": V = 7 edges = [ [0, 1], [0, 2], [1, 3], [4, 1], [6, 4], [5, 6], [5, 2], [6, 0]]

print(findMotherVertex(V, edges))

C#

using System; using System.Collections.Generic;

class GFG { // BFS traversal starting from a vertex static void bfsFromVertex(int v, bool[] visited, List<List > adj) { Queue q = new Queue();

    // Mark starting vertex visited
    visited[v] = true;
    q.Enqueue(v);

    while (q.Count > 0) {
        int node = q.Dequeue();

        foreach(int neighbor in adj[node])
        {
            if (!visited[neighbor]) {
                visited[neighbor] = true;
                q.Enqueue(neighbor);
            }
        }
    }
}

// Function to find a mother vertex using BFS
static int findMotherVertex(int V, int[][] edges)
{
    // Adjacency list
    List<List<int> > adj = new List<List<int> >();
    for (int i = 0; i < V; i++) {
        adj.Add(new List<int>());
    }

    foreach(var edge in edges)
    {
        adj[edge[0]].Add(edge[1]);
    }

    // Try BFS from every vertex
    for (int i = 0; i < V; i++) {
        bool[] visited = new bool[V];

        bfsFromVertex(i, visited, adj);

        // Check if all nodes are visited
        bool allVisited = true;
        foreach(bool v in visited)
        {
            if (!v) {
                allVisited = false;
                break;
            }
        }

        if (allVisited)
            return i;
    }

    return -1;
}

static void Main()
{
    int V = 7;

    int[][] edges = new int[][] {
        new int[] { 0, 1 }, new int[] { 0, 2 },
        new int[] { 1, 3 }, new int[] { 4, 1 },
        new int[] { 6, 4 }, new int[] { 5, 6 },
        new int[] { 5, 2 }, new int[] { 6, 0 }
    };

    Console.WriteLine(findMotherVertex(V, edges));
}

}

JavaScript

// BFS traversal starting from a vertex function bfsFromVertex(v, visited, adj) { let q = [];

// Mark starting vertex visited
visited[v] = true;
q.push(v);

while (q.length > 0) {

    let node = q.shift();

    for (let neighbor of adj[node]) {
        if (!visited[neighbor]) {
            visited[neighbor] = true;
            q.push(neighbor);
        }
    }
}

}

// Function to find a mother vertex using BFS function findMotherVertex(V, edges) { // Adjacency list let adj = Array.from({length : V}, () => []);

for (let [u, v] of edges) {
    adj[u].push(v);
}

// Try BFS from every vertex
for (let i = 0; i < V; i++) {

    let visited = new Array(V).fill(false);

    bfsFromVertex(i, visited, adj);

    // Check if all nodes are visited
    let allVisited = visited.every(v => v === true);

    if (allVisited)
        return i;
}

return -1;

}

// Driver code let V = 7;

let edges = [ [ 0, 1 ], [ 0, 2 ], [ 1, 3 ], [ 4, 1 ], [ 6, 4 ], [ 5, 6 ], [ 5, 2 ], [ 6, 0 ]];

console.log(findMotherVertex(V, edges));

`

[Expected Approach] - Using DFS (Last Finished Vertex Technique) - O(V + E) Time and O(V) Space

The approach is that if a mother vertex exists in a directed graph, it will be the **last vertex to finish in a **DFS traversal. This is because DFS may start from multiple unvisited vertices, forming a DFS forest. A mother vertex can reach all other vertices, so when DFS eventually starts from it, it will traverse the entire remaining graph in one go and finish last. Any earlier DFS starting points cannot reach all nodes (otherwise they would also be mother vertices). Therefore, the last finished vertex is the only possible candidate, and we finally verify it by checking whether it can reach all vertices.

Consider the following dry run:

V = 7, Edges = {{0, 1}, {0, 2}, {1, 3}, {4, 1}, {6, 4}, {5, 6}, {5, 2}, {6, 0}}

Final answer : 5

C++ `

#include <bits/stdc++.h> using namespace std;

// DFS traversal starting from a vertex void dfsFromVertex(int v, vector &visited, vector<vector> &adj) {

// Mark vertex visited
visited[v] = true;
for (int neighbor : adj[v])
{
    if (!visited[neighbor])
    {
        dfsFromVertex(neighbor, visited, adj);
    }
}

}

// Function to find a mother vertex int findMotherVertex(int V, vector<vector> &edges) { // Adjacency list vector<vector> adj(V); for (auto &edge : edges) { int u = edge[0]; int v = edge[1];

    adj[u].push_back(v);
}


vector<bool> visited(V, false);
int candidate = 0;

// Step 1: Find last finished vertex
for (int i = 0; i < V; i++)
{
    if (!visited[i])
    {
        dfsFromVertex(i, visited, adj);

        // Candidate mother vertex
        candidate = i;
    }
}

// Step 2: Check if candidate reaches all vertices
fill(visited.begin(), visited.end(), false);
dfsFromVertex(candidate, visited, adj);
for (bool v : visited)
    if (!v)
        return -1;

return candidate;

}

int main() { int V = 7;

vector<vector<int>> edges = {{0, 1}, {0, 2}, {1, 3}, {4, 1}, {6, 4}, {5, 6}, {5, 2}, {6, 0}};

cout << findMotherVertex(V, edges) << endl;
return 0;

}

Java

import java.util.*;

public class GFG {

// DFS traversal starting from a vertex
static void dfsFromVertex(int v, boolean[] visited,
                          List<List<Integer> > adj)
{
    // Mark vertex visited
    visited[v] = true;

    for (int neighbor : adj.get(v)) {
        if (!visited[neighbor]) {
            dfsFromVertex(neighbor, visited, adj);
        }
    }
}

// Function to find a mother vertex
static int findMotherVertex(int V, int[][] edges)
{
    // Adjacency list
    List<List<Integer> > adj = new ArrayList<>();
    for (int i = 0; i < V; i++) {
        adj.add(new ArrayList<>());
    }

    for (int[] edge : edges) {
        int u = edge[0];
        int v = edge[1];

        adj.get(u).add(v);
    }

    boolean[] visited = new boolean[V];
    int candidate = 0;

    // Step 1: Find last finished vertex
    for (int i = 0; i < V; i++) {
        if (!visited[i]) {
            dfsFromVertex(i, visited, adj);

            // Candidate mother vertex
            candidate = i;
        }
    }

    // Step 2: Check if candidate reaches all vertices
    Arrays.fill(visited, false);
    dfsFromVertex(candidate, visited, adj);

    for (boolean v : visited)
        if (!v)
            return -1;

    return candidate;
}

public static void main(String[] args)
{
    int V = 7;

    int[][] edges
        = { { 0, 1 }, { 0, 2 }, { 1, 3 }, { 4, 1 },
            { 6, 4 }, { 5, 6 }, { 5, 2 }, { 6, 0 } };

    System.out.println(findMotherVertex(V, edges));
}

}

Python

DFS traversal starting from a vertex

def dfsFromVertex(v, visited, adj):

# Mark vertex visited
visited[v] = True

for neighbor in adj[v]:
    if not visited[neighbor]:
        dfsFromVertex(neighbor, visited, adj)

Function to find a mother vertex

def findMotherVertex(V, edges):

# Adjacency list
adj = [[] for _ in range(V)]

for edge in edges:
    u = edge[0]
    v = edge[1]

    adj[u].append(v)

visited = [False] * V
candidate = 0

# Step 1: Find last finished vertex
for i in range(V):
    if not visited[i]:
        dfsFromVertex(i, visited, adj)

        # Candidate mother vertex
        candidate = i

# Step 2: Check if candidate reaches all vertices
visited = [False] * V
dfsFromVertex(candidate, visited, adj)

for v in visited:
    if not v:
        return -1

return candidate

Driver code

if name == "main": V = 7 edges = [ [0, 1], [0, 2], [1, 3], [4, 1], [6, 4], [5, 6], [5, 2], [6, 0]]

print(findMotherVertex(V, edges))

C#

using System; using System.Collections.Generic;

class GFG { // DFS traversal starting from a vertex static void dfsFromVertex(int v, bool[] visited, List<List > adj) { // Mark vertex visited visited[v] = true;

    foreach(int neighbor in adj[v])
    {
        if (!visited[neighbor]) {
            dfsFromVertex(neighbor, visited, adj);
        }
    }
}

// Function to find a mother vertex
static int findMotherVertex(int V, int[][] edges)
{
    // Adjacency list
    List<List<int> > adj = new List<List<int> >();
    for (int i = 0; i < V; i++) {
        adj.Add(new List<int>());
    }

    foreach(var edge in edges)
    {
        int u = edge[0];
        int v = edge[1];

        adj[u].Add(v);
    }

    bool[] visited = new bool[V];
    int candidate = 0;

    // Step 1: Find last finished vertex
    for (int i = 0; i < V; i++) {
        if (!visited[i]) {
            dfsFromVertex(i, visited, adj);

            // Candidate mother vertex
            candidate = i;
        }
    }

    // Step 2: Check if candidate reaches all vertices
    Array.Fill(visited, false);
    dfsFromVertex(candidate, visited, adj);

    foreach(bool v in visited) if (!v) return -1;

    return candidate;
}

static void Main()
{
    int V = 7;

    int[][] edges = new int[][] {
        new int[] { 0, 1 }, new int[] { 0, 2 },
        new int[] { 1, 3 }, new int[] { 4, 1 },
        new int[] { 6, 4 }, new int[] { 5, 6 },
        new int[] { 5, 2 }, new int[] { 6, 0 }
    };

    Console.WriteLine(findMotherVertex(V, edges));
}

}

JavaScript

// DFS traversal starting from a vertex function dfsFromVertex(v, visited, adj) { // Mark vertex visited visited[v] = true;

for (let neighbor of adj[v]) {
    if (!visited[neighbor]) {
        dfsFromVertex(neighbor, visited, adj);
    }
}

}

// Function to find a mother vertex function findMotherVertex(V, edges) { // Adjacency list let adj = Array.from({length : V}, () => []);

for (let edge of edges) {
    let u = edge[0];
    let v = edge[1];

    adj[u].push(v);
}

let visited = new Array(V).fill(false);
let candidate = 0;

// Step 1: Find last finished vertex
for (let i = 0; i < V; i++) {
    if (!visited[i]) {
        dfsFromVertex(i, visited, adj);

        // Candidate mother vertex
        candidate = i;
    }
}

// Step 2: Check if candidate reaches all vertices
visited.fill(false);
dfsFromVertex(candidate, visited, adj);

for (let v of visited)
    if (!v)
        return -1;

return candidate;

}

// Driver code let V = 7;

let edges = [ [ 0, 1 ], [ 0, 2 ], [ 1, 3 ], [ 4, 1 ], [ 6, 4 ], [ 5, 6 ], [ 5, 2 ], [ 6, 0 ] ];

console.log(findMotherVertex(V, edges));

`