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++ 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 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 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# 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. |
<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> |
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.