Count of graphs formed by changing color of any red-colored node with black parent to black
Last Updated :
08 Mar, 2023
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:
- 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.
- 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.
- 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.
- 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++
#include <bits/stdc++.h>
using namespace std;
int V;
vector< int > graph[100];
void addEdge( int u, int v)
{
graph[u].push_back(v);
}
int numOfGraph( int u)
{
if (graph[u].size() == 0)
return 2;
int cnt = 1;
for ( int i:graph[u])
{
cnt *= numOfGraph(i);
}
return cnt + 1;
}
int main()
{
V = 5;
addEdge(1, 2);
addEdge(1, 3);
addEdge(2, 4);
addEdge(2, 5);
int K = 1;
cout << (numOfGraph(K) - 1);
return 0;
}
|
Java
import java.util.*;
class Graph{
static void addEdge( int u, int v,
ArrayList<ArrayList<Integer>> graph)
{
graph.get(u).add(v);
}
static int numOfGraph( int u,
ArrayList<ArrayList<Integer>> graph)
{
if (graph.get(u).size() == 0 )
return 2 ;
int cnt = 1 ;
for ( int i:graph.get(u))
{
cnt *= numOfGraph(i,graph);
}
return cnt + 1 ;
}
public static void main(String[] args)
{
int V;
ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
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);
int K = 1 ;
System.out.println((numOfGraph(K, graph) - 1 ));
}
}
|
Python3
from collections import defaultdict
class Graph:
def __init__( self , vertices):
self .V = vertices
self .graph = defaultdict( list )
def addEdge( self , u, v):
self .graph[u].append(v)
def numOfGraph( self , u):
if u not in self .graph:
return 2
cnt = 1
for i in self .graph[u]:
cnt * = self .numOfGraph(i)
return cnt + 1
if __name__ = = "__main__" :
g = Graph( 5 )
g.addEdge( 1 , 2 )
g.addEdge( 1 , 3 )
g.addEdge( 2 , 4 )
g.addEdge( 2 , 5 )
K = 1
print (g.numOfGraph(K) - 1 )
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class Graph{
static int V;
static LinkedList< int >[] 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 >();
}
}
static int numOfGraph( int u)
{
if (graph[u].Count == 0)
return 2;
int cnt = 1;
foreach ( var i in graph[u])
{
cnt *= numOfGraph(i);
}
return cnt + 1;
}
static public void Main (){
V = 5;
Graph g = new Graph(100);
g.addEdge(1, 2);
g.addEdge(1, 3);
g.addEdge(2, 4);
g.addEdge(2, 5);
int K = 1;
Console.WriteLine(numOfGraph(K) - 1);
}
}
|
Javascript
<script>
let V;
let graph = new Array(100);
for (let i = 0; i < 100; i++)
{
graph[i] = []
}
function addEdge(u, v)
{
graph[u].push(v);
}
function numOfGraph(u)
{
if (graph[u].length == 0)
return 2;
let cnt = 1;
for (let i = 0; i < graph[u].length; i++)
{
cnt *= numOfGraph(graph[u][i]);
}
return cnt + 1;
}
V = 5;
addEdge(1, 2);
addEdge(1, 3);
addEdge(2, 4);
addEdge(2, 5);
let K = 1;
document.write(numOfGraph(K) - 1);
</script>
|
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.
Share your thoughts in the comments
Please Login to comment...