给定一个由N 个节点和N-1 条边组成的有向图G ,以及一个正整数K,并且最初,图中除了K是黑色之外的所有节点都是红色的,任务是计算不同可能的数量通过将任何红色节点的颜色更改为黑色而形成的图形,仅当它们的父节点为黑色时,任意次数。
例子:
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
方法:该问题可以基于以下观察来解决:
- 给定的有向图可以被视为以节点K为根的树。不同可能图的数量与相应地为图着色的方法数量相同。
- 仅当父节点为黑色时,任何节点的子节点都可以为黑色。因此,从K到当前节点的所有节点都必须为黑色。
- 因此,想法是从K执行 DFS 遍历,并且对于每个节点,要么将当前节点着色为黑色,要么保持原样。然后仅当当前节点为黑色时才遍历子树。
- 如果当前节点U有3个子节点,并且X、Y、Z是节点U的子节点的子树着色方式的数量。那么当前子树的着色方式总数为(X*Y* Z+1)。节点K不能着色,因此节点K不加1 。
请按照以下步骤解决问题:
- 从图的给定边形成邻接表并将其存储在变量中,例如图
- 定义一个递归函数,比如numOfGraph(U) ,其中U是当前节点:
- 如果节点U是叶子,则返回2 。因为节点可以是黑色或红色。
- 初始化一个变量,比如cnt ,它存储为图形着色的方法数。
- 使用变量i迭代与当前节点U连接的节点,并执行以下步骤:
- 通过递归调用函数儿童节点i更新CNT至CNT * NumberOfGraph(i)的值。
- 经过以上步骤,返回cnt+1的值。
- 最后,从节点K调用 DFS函数,即numOfGraph(K) ,并将其返回的值打印为答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Class to represents a directed graph
// using adjacency list representation
// Constructor
int V;
vector 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> graph)
{
graph.get(u).add(v);
}
// Function to count number of
// possible graphs with given
// coloring
static int numOfGraph(int u,
ArrayList> 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> 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[] 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[v];
for(int i = 0; i <= V; i++)
{
graph[i] = new LinkedList();
}
}
// 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
10
时间复杂度: 在)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。