Open In App

Count of graphs formed by changing color of any red-colored node with black parent to black

Improve
Improve
Like Article
Like
Save
Share
Report

Given a directed graph G consisting of N nodes and N-1 edges, and a positive integer K, and initially, all the nodes of the graph are red except for K, which is black, the task is to count the number of different possible graphs formed by changing the color of any red-colored node to black, only if their parent is colored black, any number of times.

Examples:

Input: N = 5, K = 1, Edges[] = {{1, 2}, {1, 3}, {2, 4}, {2, 5}}
Output: 10
Explanation: 
When node 2 is red then we can’t change the color of 4 and 5 because its parent(2) is not black. Therefore, there is only one possible way to color. 

                                        1(B)
                                     /        \
                                2(R)          3(R)
                             /         \
                         4(R)        5(R)
But when 2 is black, then we can change the color of 4 and 5 (4 and 5 are independent of each other) in 2 possible ways, each(red-black) because its parent(2) is black.

Node 3 again can be colored in 2 different ways. Therefore, the total number of ways of coloring is (5*2 = 10). Thus there are a total of 10 different possible graphs.

Input: N = 3, K = 2, Edges[] = {{1, 2}, {1, 3}}
Output: 1

Approach: The problem can be solved based on the following observations:

  1. The given directed graph can be treated as a tree rooted at node K. And the number of different possible graphs is the same as the number of ways to color the graph accordingly.
  2. The children of any node can be colored black only if the parent node is colored black. Therefore, all the nodes from the K to the current node must be colored black.
  3. Therefore, the idea is to perform a DFS traversal from the K, and for each node either color the current node black or leave it as it is. Then traversing the subtrees only if the current node is colored black.
  4. If there are 3 children of current node U, and X, Y, Z is the number of ways to color the subtrees of the children of the node U. Then the total number of ways to color the current subtree is (X*Y*Z+1). Node K can not be colored, so 1 is not added to node K.

 Follow the steps below to solve the problem:

  • Form an adjacency list from the given edges of the graph and store it in a variable, say graph
  • Define a recursive function, say, numOfGraph(U) where U is the current node:
    • If node U is the leaf, then return 2. As the node can be colored either black or red.
    • Initialize a variable, say cnt, that stores the number of ways to color the graph.
    • Iterate over the node connected with current node U, using the variable i, and perform the following steps:
      • Update the value of cnt to cnt*NumberOfGraph(i) by recursively calling the function for children node i.
    • After the above steps, return the value of cnt+1.
  • Finally, call the DFS function from node K i.e numOfGraph(K), and print the value returned by it as the answer.

Below is the implementation of the above approach: 

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Class to represents a directed graph
// using adjacency list representation
 
// Constructor
int V;
 
vector<int> graph[100];
 
// Function to add an edge in an directed
// graph
void addEdge(int u, int v)
{
    graph[u].push_back(v);
}
 
// Function to count number of
// possible graphs with given
// coloring
int numOfGraph(int u)
{
     
    // If node is leaf node
    if (graph[u].size() == 0)
        return 2;
         
    // Stores the number of ways to
    // color the subtree of node u
    int cnt = 1;
 
    // Traverse over the children of
    // node u
    for(int i:graph[u])
    {
         
        // Multiply number of possible ways
        // to color the subtree
        cnt *= numOfGraph(i);
    }
     
    // Return cnt
    return cnt + 1;
}
 
// Driver code
int main()
{
     
    // Create a graph
    V = 5;
    addEdge(1, 2);
    addEdge(1, 3);
    addEdge(2, 4);
    addEdge(2, 5);
     
    // Node initially in black
    int K = 1;
     
    // Function Call
    cout << (numOfGraph(K) - 1);
     
    return 0;
}
 
// This code is contributed by Mohit kumar


Java




// Java program for above approach
import java.util.*;
 
class Graph{
 
// Function to add an edge in an directed
// graph
static void addEdge(int u, int v,
                    ArrayList<ArrayList<Integer>> graph)
{
    graph.get(u).add(v);
}
 
// Function to count number of
// possible graphs with given
// coloring
static int numOfGraph(int u,
                      ArrayList<ArrayList<Integer>> graph)
{
     
    // If node is leaf node
    if (graph.get(u).size() == 0)
        return 2;
 
    // Stores the number of ways to
    // color the subtree of node u
    int cnt = 1;
 
    // Traverse over the children of
    // node u
    for(int i:graph.get(u))
    {
         
        // Multiply number of possible ways
        // to color the subtree
        cnt *= numOfGraph(i,graph);
    }
 
    // Return cnt
    return cnt + 1;
}
 
// Driver code
public static void main(String[] args)
{
     
    // Represents a directed graph
    // using adjacency list representation
    int V;
 
    ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
 
    // Create a graph
    V = 5;
    for(int i = 0; i <= V; i++)
        graph.add(new ArrayList<>());
         
    addEdge(1, 2, graph);
    addEdge(1, 3, graph);
    addEdge(2, 4, graph);
    addEdge(2, 5, graph);
 
    // Node initially in black
    int K = 1;
 
    // Function Call
    System.out.println((numOfGraph(K, graph) - 1));
}
}
 
// This code is contributed by hritikrommie


Python3




# Python3 program for the above approach
 
# Import library for create defaultdict
from collections import defaultdict
 
# Class to represents a directed graph
# using adjacency list representation
 
 
class Graph:
 
    # Constructor
    def __init__(self, vertices):
        self.V = vertices
        self.graph = defaultdict(list)
 
    # Function to add an edge in an directed
    # graph
    def addEdge(self, u, v):
        self.graph[u].append(v)
 
    # Function to count number of
    # possible graphs with given
    # coloring
    def numOfGraph(self, u):
 
        # If node is leaf node
        if u not in self.graph:
            return 2
            # Stores the number of ways to
        # color the subtree of node u
        cnt = 1
 
        # Traverse over the children of
        # node u
        for i in self.graph[u]:
            # Multiply number of possible ways
            # to color the subtree
            cnt *= self.numOfGraph(i)
 
        # Return cnt
        return cnt + 1
 
 
# Driver code
if __name__ == "__main__":
 
    # Create a graph
    g = Graph(5)
    g.addEdge(1, 2)
    g.addEdge(1, 3)
    g.addEdge(2, 4)
    g.addEdge(2, 5)
 
    # Node initially in black
    K = 1
 
    # Function Call
    print(g.numOfGraph(K)-1)


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
  
 
public class Graph{
 
static int V;
  
//Adjacency Lists
static LinkedList<int>[] graph;
  
// Function to add an edge in an directed
// graph
public void addEdge(int u, int v)
{       
    graph[u].AddLast(v);
}
   
public Graph(int v)
{
    graph = new LinkedList<int>[v];
    for(int i = 0; i <= V; i++)
    {
        graph[i] = new LinkedList<int>();
    }
}
   
// Function to count number of
// possible graphs with given
// coloring
static int numOfGraph(int u)
{
     
    // If node is leaf node
    if (graph[u].Count == 0)
        return 2;
         
    // Stores the number of ways to
    // color the subtree of node u
    int cnt = 1;
 
    // Traverse over the children of
    // node u
    foreach (var i in graph[u])
    {
         
        // Multiply number of possible ways
        // to color the subtree
        cnt *= numOfGraph(i);
    }
     
    // Return cnt
    return cnt + 1;
}
 
// Driver code
static public void Main (){
     
      V = 5;
   
    // Create a graph
      Graph g = new Graph(100);
   
    g.addEdge(1, 2);
    g.addEdge(1, 3);
    g.addEdge(2, 4);
    g.addEdge(2, 5);
     
    // Node initially in black
    int K = 1;
     
    // Function Call
    Console.WriteLine(numOfGraph(K) - 1);
}
}
 
// This code is contributed by Dharanendra L V.


Javascript




<script>
    // Javascript program for the above approach
     
    let V;
   
    //Adjacency Lists
    let graph = new Array(100);
    for(let i = 0; i < 100; i++)
    {
        graph[i] = []
    }
 
    // Function to add an edge in an directed
    // graph
    function addEdge(u, v)
    {      
        graph[u].push(v);
    }
 
    // Function to count number of
    // possible graphs with given
    // coloring
    function numOfGraph(u)
    {
 
        // If node is leaf node
        if (graph[u].length == 0)
            return 2;
 
        // Stores the number of ways to
        // color the subtree of node u
        let cnt = 1;
 
        // Traverse over the children of
        // node u
        for(let i = 0; i < graph[u].length; i++)
        {
 
            // Multiply number of possible ways
            // to color the subtree
            cnt *= numOfGraph(graph[u][i]);
        }
 
        // Return cnt
        return cnt + 1;
    }
     
    // Create a graph
    V = 5;
    addEdge(1, 2);
    addEdge(1, 3);
    addEdge(2, 4);
    addEdge(2, 5);
      
    // Node initially in black
    let K = 1;
      
    // Function Call
    document.write(numOfGraph(K) - 1);
 
// This code is contributed by decode2207.
</script>


Output

10

Time Complexity: O(N) where N is the total number of nodes in the graph.
Auxiliary Space:  O(V+E) where V is the number of vertices and E is the number of edges in the graph.



Last Updated : 08 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads