给定一棵树,由N 个节点组成,从[1, N]编号,颜色为黑色(用 1 表示)或绿色(用 0 表示) ,任务是计算长度为K [a 1 , a 2的序列的数量, ..a K ] 使得在连续节点之间采取的路径是最短的,并且覆盖的边由至少一个黑色边组成。由于答案可能很大,请将其打印为10 9 +7 的模数。
Input: N = 4, K = 4
1-2 0
2-3 0
2-4 0
Output: 0
Explanation:
Since there is no black edge in the tree. There are no such sequences.
Input: N = 3, K = 3
1-2 1
2-3 1
Output: 24
Explanation:
All the 33 sequences except for (1, 1, 1), (2, 2, 2) and (3, 3, 3) are included in the answer.
方法:
这个想法是计算长度为K的序列的数量,使得没有黑边被覆盖。让计数为temp 。那么(N K ) – temp是必需的答案。通过去除黑边,然后计算结果图的不同组件的大小,可以轻松计算temp 。
请按照以下步骤操作:
- 将ans的值初始化为N K 。
- 通过仅添加绿色边构建图G。
- 对图执行 DFS 遍历并不断从ans中减去(大小K ) ,其中大小是图 G 的不同组件中的节点数。
下面是上述方法的实现:
C++
// C++ implementation of the
// above approach
#include
#define int long long int
using namespace std;
const int mod = 1e9 + 7;
const int N = 1e5 + 1;
// Vector to store the graph
vector G[N];
// Iterative Function to calculate
// (ab) % mod in O(log b)
int power(int a, int b) {
// Initialize result
int res = 1;
// Update x if it is more than
// or equal to p
a = a % mod;
if (a == 0)
// In case x is divisible by p;
return 0;
while (b > 0) {
// If a is odd,
// multiply x with result
if (b & 1)
res = (res * a) % mod;
// b must be even now
b = b >> 1; // b = b/2
a = (a * a) % mod;
}
return res;
}
// DFS traversal of the nodes
void dfs(int i, int& size,
bool* visited) {
// Mark the current
// node as visited
visited[i] = true;
// Increment the size of the
// current component
size++;
// Recur for all the vertices
// adjacent to this node
for (auto nbr : G[i]) {
if (!visited[nbr]) {
dfs(nbr, size, visited);
}
}
}
// Function to calculate the
// final answer
void totalSequences(int& ans,
int n, int k)
{
// Mark all the vertices as
// not visited initially
bool visited[n + 1];
memset(visited, false,
sizeof(visited));
// Subtract (size^k) from the answer
// for different components
for (int i = 1; i <= n; i++) {
if (!visited[i]) {
int size = 0;
dfs(i, size, visited);
ans -= power(size, k);
ans += mod;
ans = ans % mod;
}
}
}
// Function to add edges to the graph
void addEdge(int x, int y, int color)
{
// If the colour is green,
// include it in the graph
if (color == 0) {
G[x].push_back(y);
G[y].push_back(x);
}
}
int32_t main()
{
// Number of node in the tree
int n = 3;
// Size of sequence
int k = 3;
// Initiaize the result as n^k
int ans = power(n, k);
/* 2
/ \
1 3
Let us create binary tree as shown
in above example */
addEdge(1, 2, 1);
addEdge(2, 3, 1);
totalSequences(ans, n, k);
cout << ans << endl;
}
Java
// Java implementation of the
// above approach
import java.util.*;
class GFG{
static int mod = (int)(1e9 + 7);
static int N = (int)(1e5 + 1);
static int size;
static int ans;
// Vector to store the graph
@SuppressWarnings("unchecked")
static Vector []G = new Vector[N];
// Iterative Function to calculate
// (ab) % mod in O(log b)
static int power(int a, int b)
{
// Initialize result
int res = 1;
// Update x if it is more than
// or equal to p
a = a % mod;
if (a == 0)
// In case x is divisible by p;
return 0;
while (b > 0)
{
// If a is odd,
// multiply x with result
if (b % 2 == 1)
res = (res * a) % mod;
// b must be even now
b = b >> 1; // b = b/2
a = (a * a) % mod;
}
return res;
}
// DFS traversal of the nodes
static void dfs(int i, boolean []visited)
{
// Mark the current
// node as visited
visited[i] = true;
// Increment the size of the
// current component
size++;
// Recur for all the vertices
// adjacent to this node
for(int nbr : G[i])
{
if (!visited[nbr])
{
dfs(nbr, visited);
}
}
}
// Function to calculate the
// final answer
static void totalSequences(int n, int k)
{
// Mark all the vertices as
// not visited initially
boolean []visited = new boolean[n + 1];
// Subtract (size^k) from the answer
// for different components
for(int i = 1; i <= n; i++)
{
if (!visited[i])
{
size = 0;
dfs(i, visited);
ans -= power(size, k);
ans += mod;
ans = ans % mod;
}
}
}
// Function to add edges to the graph
static void addEdge(int x, int y, int color)
{
// If the colour is green,
// include it in the graph
if (color == 0)
{
G[x].add(y);
G[y].add(x);
}
}
// Driver code
public static void main(String[] args)
{
for(int i = 0; i < G.length; i++)
G[i] = new Vector();
// Number of node in the tree
int n = 3;
// Size of sequence
int k = 3;
// Initiaize the result as n^k
ans = power(n, k);
/* 2
/ \
1 3
Let us create binary tree as shown
in above example */
addEdge(1, 2, 1);
addEdge(2, 3, 1);
totalSequences(n, k);
System.out.print(ans + "\n");
}
}
// This code is contributed by Amit Katiyar
Python3
# Python3 program for the above approach
mod = 1e9 + 7
N = 1e5 + 1
# List to store the graph
G = [0] * int(N)
# Iterative Function to calculate
# (ab) % mod in O(log b)
def power(a, b):
# Initialize result
res = 1
# Update x if it is more than
# or equal to p
a = a % mod
if a == 0:
# In case x is divisible by p;
return 0
while b > 0:
# If a is odd,
# multiply x with result
if b & 1:
res = (res * a) % mod
# b must be even now
b = b >> 1 # b = b/2
a = (a * a) % mod
return res
# DFS traversal of the nodes
def dfs(i, size, visited):
# Mark the current
# node as visited
visited[i] = True
# Increment the size of the
# current component
size[0] += 1
# Recur for all the vertices
# adjacent to this node
for nbr in range(G[i]):
if not visited[nbr]:
dfs(nbr, size, visited)
# Function to calculate the
# final answer
def totalSequences(ans, n, k):
# Mark all the vertices as
# not visited initially
visited = [False] * (n + 1)
# Subtract (size^k) from the answer
# for different components
for i in range(1, n + 1):
if not visited[i]:
size = [0]
dfs(i, size, visited)
ans[0] -= power(size[0], k)
ans[0] += mod
ans[0] = ans[0] % mod
# Function to add edges to the graph
def addEdge(x, y, color):
# If the colour is green,
# include it in the graph
if color == 0:
G[x].append(y)
G[y].append(x)
# Driver code
if __name__ == '__main__':
# Number of node in the tree
n = 3
# Size of sequence
k = 3
# Initiaize the result as n^k
ans = [power(n, k)]
"""
2
/ \
1 3
Let us create binary tree as shown
in above example
"""
addEdge(1, 2, 1)
addEdge(2, 3, 1)
totalSequences(ans, n, k)
print(int(ans[0]))
# This code is contributed by Shivam Singh
C#
// C# implementation of the
// above approach
using System;
using System.Collections.Generic;
class GFG{
static int mod = (int)(1e9 + 7);
static int N = (int)(1e5 + 1);
static int size;
static int ans;
// List to store the graph
static List []G =
new List[N];
// Iterative Function to
// calculate (ab)
// % mod in O(log b)
static int power(int a,
int b)
{
// Initialize result
int res = 1;
// Update x if it is
// more than or equal
// to p
a = a % mod;
if (a == 0)
// In case x is
// divisible by p;
return 0;
while (b > 0)
{
// If a is odd,
// multiply x
// with result
if (b % 2 == 1)
res = (res * a) % mod;
// b must be even now
// b = b/2
b = b >> 1;
a = (a * a) % mod;
}
return res;
}
// DFS traversal of the nodes
static void dfs(int i,
bool []visited)
{
// Mark the current
// node as visited
visited[i] = true;
// Increment the size of the
// current component
size++;
// Recur for all the vertices
// adjacent to this node
foreach(int nbr in G[i])
{
if (!visited[nbr])
{
dfs(nbr, visited);
}
}
}
// Function to calculate the
// readonly answer
static void totalSequences(int n,
int k)
{
// Mark all the vertices as
// not visited initially
bool []visited = new bool[n + 1];
// Subtract (size^k) from the
// answer for different components
for(int i = 1; i <= n; i++)
{
if (!visited[i])
{
size = 0;
dfs(i, visited);
ans -= power(size, k);
ans += mod;
ans = ans % mod;
}
}
}
// Function to add edges
// to the graph
static void addEdge(int x,
int y,
int color)
{
// If the colour is green,
// include it in the graph
if (color == 0)
{
G[x].Add(y);
G[y].Add(x);
}
}
// Driver code
public static void Main(String[] args)
{
for(int i = 0; i < G.Length; i++)
G[i] = new List();
// Number of node
// in the tree
int n = 3;
// Size of sequence
int k = 3;
// Initiaize the
// result as n^k
ans = power(n, k);
/* 2
/ \
1 3
Let us create binary tree
as shown in above example */
addEdge(1, 2, 1);
addEdge(2, 3, 1);
totalSequences(n, k);
Console.Write(ans + "\n");
}
}
// This code is contributed by Rajput-Ji
24
时间复杂度: O(N),因为 DFS 遍历需要 O(Vertices + Edges) == O(N + (N-1)) == O(N) ) 复杂度。
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live