Open In App

Find the Dominators for every vertex in a given DAG (Directed Acyclic Graph)

Given a Directed Acyclic Graph with V vertices and E edges, the task is to find the set of dominant vertices for each vertex of the graph.

What are Dominators in Graph Theory: In control flow graphs a vertex V1 is the dominator of another vertex V2 if all the paths from the source vertex (in this case the vertex ‘0’) to the vertex V2 passes through V1. By definition, every vertex is one of its own dominators.

Examples:

Input: V = 5, E = 5, adj[][] = {{0, 1}, {0, 2}, {1, 3}, {2, 3}, {3, 4}}
Output:
Dominating set of vertex: 0 –> 0 
Dominating set of vertex: 1 –> 0 1 
Dominating set of vertex: 2 –> 0 2 
Dominating set of vertex: 3 –> 0 3 
Dominating set of vertex: 4 –> 0 3 4
Explanation:
          0
       /     \
     1        2
      \      /
         3
         |
        4          
Here 0 is the entry node, so its dominator is 0 itself.
Only one path exists between (0, 1) so the dominators of 1 are 0, 1.
Only one path exists between (0, 2) so the dominators of 2 are 0, 2.
There are 2 paths between(0, 3) having only 0, 3 in common.
From (0, 4) there are 2 paths (0 1 3 4) and (0 2 3 4) with 0, 3 and 4 common.

Input: V = 4, E = 3, adj[][] = {{0, 1}, {0, 2}, {3, 2}}
Output:
Dominating set of vertex: 0 –> 0 
Dominating set of vertex: 1 –> 0 1 
Dominating set of vertex: 2 –> 0 2 
Dominating set of vertex: 3 –> 0 2 3

Approach: The idea is to perform DFS and maintain a set of all the dominators of each vertex. Follow the steps below to solve the problem:

Below is the implementation of the above approach:

import java.util.*;

public class Dominators {
    public static void findDominators(int V, int[][] edges) {
        // Initialize graph
        Map<Integer, List<Integer>> graph = new HashMap<>();
        for (int[] edge : edges) {
            graph.computeIfAbsent(edge[0], k -> new ArrayList<>()).add(edge[1]);
        }
        
        // Initialize the list of dominators
        List<Set<Integer>> dominators = new ArrayList<>(V);
        for (int i = 0; i < V; i++) {
            dominators.add(new HashSet<>());
        }
        
        // Initialize a list of incoming edges count for each vertex
        int[] inDegrees = new int[V];
        for (int[] edge : edges) {
            inDegrees[edge[1]]++;
        }
        
        // Initialize the dominator set for the entry node (source node 0)
        dominators.get(0).add(0);
        
        // Initialize a queue for BFS traversal
        Queue<Integer> queue = new LinkedList<>();
        queue.add(0);
        
        // Perform BFS
        while (!queue.isEmpty()) {
            int u = queue.poll();
            
            // Traverse neighbors of the current vertex
            for (int v : graph.getOrDefault(u, new ArrayList<>())) {
                // Calculate the intersection of dominators from all predecessors of v
                if (dominators.get(v).isEmpty()) {
                    dominators.get(v).addAll(dominators.get(u));
                    dominators.get(v).add(v);
                } else {
                    dominators.get(v).retainAll(dominators.get(u));
                }
                
                // Reduce the in-degree count for vertex v
                inDegrees[v]--;
                
                // If all predecessors of v have been processed, add v to the queue
                if (inDegrees[v] == 0) {
                    queue.add(v);
                }
            }
        }
        
        // Print the dominator sets for each vertex
        for (int i = 0; i < V; i++) {
            System.out.print("Dominating set of vertex " + i + ": ");
            List<Integer> sortedDominators = new ArrayList<>(dominators.get(i));
            Collections.sort(sortedDominators);
            for (int dominator : sortedDominators) {
                System.out.print(dominator + " ");
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        int V = 5;
        int[][] edges = {{0, 1}, {0, 2}, {1, 3}, {2, 3}, {3, 4}};
        findDominators(V, edges);
    }
}
from collections import defaultdict, deque

def find_dominators(V, edges):
    # Initialize graph
    graph = defaultdict(list)
    for u, v in edges:
        graph[u].append(v)
    
    # Initialize the list of dominators
    dominators = [set() for _ in range(V)]
    
    # Initialize a list of incoming edges count for each vertex
    in_degrees = [0] * V
    for u, v in edges:
        in_degrees[v] += 1
    
    # Initialize the dominator set for the entry node (source node 0)
    dominators[0] = {0}
    
    # Initialize a queue for BFS traversal
    queue = deque([0])
    
    # Perform BFS
    while queue:
        u = queue.popleft()
        
        # Traverse neighbors of current vertex
        for v in graph[u]:
            # Calculate the intersection of dominators from all predecessors of v
            if not dominators[v]:
                dominators[v] = dominators[u].copy()
                dominators[v].add(v)
            else:
                dominators[v].intersection_update(dominators[u])
            
            # Reduce the in-degree count for vertex v
            in_degrees[v] -= 1
            
            # If all predecessors of v have been processed, add v to the queue
            if in_degrees[v] == 0:
                queue.append(v)
    
    # Print the dominator sets for each vertex
    for i in range(V):
        print(f"Dominating set of vertex {i}: {sorted(dominators[i])}")

# Example usage:
V = 5
edges = [(0, 1), (0, 2), (1, 3), (2, 3), (3, 4)]
find_dominators(V, edges)
using System;
using System.Collections.Generic;

public class Dominators
{
    public static void FindDominators(int V, int[][] edges)
    {
        // Initialize graph
        Dictionary<int, List<int>> graph = new Dictionary<int, List<int>>();
        foreach (var edge in edges)
        {
            if (!graph.ContainsKey(edge[0]))
                graph[edge[0]] = new List<int>();
            graph[edge[0]].Add(edge[1]);
        }
        
        // Initialize the list of dominators
        List<HashSet<int>> dominators = new List<HashSet<int>>(V);
        for (int i = 0; i < V; i++)
        {
            dominators.Add(new HashSet<int>());
        }
        
        // Initialize a list of incoming edges count for each vertex
        int[] inDegrees = new int[V];
        foreach (var edge in edges)
        {
            inDegrees[edge[1]]++;
        }
        
        // Initialize the dominator set for the entry node (source node 0)
        dominators[0].Add(0);
        
        // Initialize a queue for BFS traversal
        Queue<int> queue = new Queue<int>();
        queue.Enqueue(0);
        
        // Perform BFS
        while (queue.Count > 0)
        {
            int u = queue.Dequeue();
            
            // Traverse neighbors of the current vertex
            if (graph.TryGetValue(u, out var neighbors))
            {
                foreach (var v in neighbors)
                {
                    // Calculate the intersection of dominators from all predecessors of v
                    if (dominators[v].Count == 0)
                    {
                        dominators[v].UnionWith(dominators[u]);
                        dominators[v].Add(v);
                    }
                    else
                    {
                        dominators[v].IntersectWith(dominators[u]);
                    }
                    
                    // Reduce the in-degree count for vertex v
                    inDegrees[v]--;
                    
                    // If all predecessors of v have been processed, add v to the queue
                    if (inDegrees[v] == 0)
                    {
                        queue.Enqueue(v);
                    }
                }
            }
        }
        
        // Print the dominator sets for each vertex
        for (int i = 0; i < V; i++)
        {
            Console.Write($"Dominating set of vertex {i}: ");
            var sortedDominators = new List<int>(dominators[i]);
            sortedDominators.Sort();
            foreach (var dominator in sortedDominators)
            {
                Console.Write(dominator + " ");
            }
            Console.WriteLine();
        }
    }

    public static void Main()
    {
        int V = 5;
        int[][] edges = new int[][] { new int[] { 0, 1 }, new int[] { 0, 2 }, new int[] { 1, 3 }, new int[] { 2, 3 }, new int[] { 3, 4 } };
        FindDominators(V, edges);
    }
}
function findDominators(V, edges) {
    // Initialize graph
    const graph = {};
    for (const [u, v] of edges) {
        if (!graph[u]) graph[u] = [];
        graph[u].push(v);
    }

    // Initialize the list of dominators
    const dominators = Array.from({ length: V }, () => new Set());

    // Initialize a list of incoming edges count for each vertex
    const inDegrees = new Array(V).fill(0);
    for (const [u, v] of edges) {
        inDegrees[v]++;
    }

    // Initialize the dominator set for the entry node (source node 0)
    dominators[0].add(0);

    // Initialize a queue for BFS traversal
    const queue = [0];

    // Perform BFS
    while (queue.length > 0) {
        const u = queue.shift();

        // Traverse neighbors of the current vertex
        if (graph[u]) {
            for (const v of graph[u]) {
                // Calculate the intersection of dominators from all predecessors of v
                if (dominators[v].size === 0) {
                    dominators[v] = new Set([...dominators[u]]);
                    dominators[v].add(v);
                } else {
                    dominators[v] = new Set([...dominators[v]].filter(val => dominators[u].has(val)));
                }
                
                // Reduce the in-degree count for vertex v
                inDegrees[v]--;

                // If all predecessors of v have been processed, add v to the queue
                if (inDegrees[v] === 0) {
                    queue.push(v);
                }
            }
        }
    }

    // Print the dominator sets for each vertex
    for (let i = 0; i < V; i++) {
        console.log(`Dominating set of vertex ${i}: ${[...dominators[i]].sort().join(' ')}`);
    }
}

// Example usage:
const V = 5;
const edges = [[0, 1], [0, 2], [1, 3], [2, 3], [3, 4]];
findDominators(V, edges);
#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
#include <set>
#include <algorithm>

using namespace std;

void findDominators(int V, const vector<pair<int, int>>& edges) {
    // Initialize graph
    unordered_map<int, vector<int>> graph;
    for (const auto& edge : edges) {
        graph[edge.first].push_back(edge.second);
    }
    
    // Initialize the list of dominators
    vector<set<int>> dominators(V);
    
    // Initialize a list of incoming edges count for each vertex
    vector<int> inDegrees(V, 0);
    for (const auto& edge : edges) {
        inDegrees[edge.second]++;
    }
    
    // Initialize the dominator set for the entry node (source node 0)
    dominators[0].insert(0);
    
    // Initialize a queue for BFS traversal
    queue<int> q;
    q.push(0);
    
    // Perform BFS
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        
        // Traverse neighbors of the current vertex
        for (int v : graph[u]) {
            // Calculate the intersection of dominators from all predecessors of v
            if (dominators[v].empty()) {
                dominators[v] = dominators[u];
                dominators[v].insert(v);
            } else {
                set<int> intersection;
                set_intersection(
                    dominators[v].

Output
0 -> 0 
1 -> 0 1 
2 -> 0 2 
3 -> 0 3 
4 -> 0 3 4 

Time Complexity: O(V + E)
Auxiliary Space: O(V2)

Article Tags :