Given a tree consisting of N nodes numbered from [1, N] and is colored either black(denoted by 1) or green(denoted by 0), the task is to count the number of sequences of length K [a1, a2, ..aK] such that the path taken between consecutive nodes is the shortest one and the edges covered consist of at least one black edge. Since the answer can be large, print it to modulo of 109+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.
Approach:
The idea is to count the number of sequences of length K such that no black edge is covered. Let the count be temp. Then (NK) – temp is the required answer. temp can be easily calculated by removing the black edges and then calculating the size of different components of the resultant graph.
Follow the steps below:
- Initialize the value of ans as NK.
- Construct a graph G by adding only green edges.
- Perform a DFS traversal of the graph and keep subtracting (sizeK) from the ans where size is the number of nodes in different components of the graph G.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
#define int long long int
using namespace std;
const int mod = 1e9 + 7;
const int N = 1e5 + 1;
vector< int > G[N];
int power( int a, int b) {
int res = 1;
a = a % mod;
if (a == 0)
return 0;
while (b > 0) {
if (b & 1)
res = (res * a) % mod;
b = b >> 1;
a = (a * a) % mod;
}
return res;
}
void dfs( int i, int & size,
bool * visited) {
visited[i] = true ;
size++;
for ( auto nbr : G[i]) {
if (!visited[nbr]) {
dfs(nbr, size, visited);
}
}
}
void totalSequences( int & ans,
int n, int k)
{
bool visited[n + 1];
memset (visited, false ,
sizeof (visited));
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;
}
}
}
void addEdge( int x, int y, int color)
{
if (color == 0) {
G[x].push_back(y);
G[y].push_back(x);
}
}
int32_t main()
{
int n = 3;
int k = 3;
int ans = power(n, k);
addEdge(1, 2, 1);
addEdge(2, 3, 1);
totalSequences(ans, n, k);
cout << ans << endl;
}
|
Java
import java.util.*;
class GFG{
static int mod = ( int )(1e9 + 7 );
static int N = ( int )(1e5 + 1 );
static int size;
static int ans;
@SuppressWarnings ( "unchecked" )
static Vector<Integer> []G = new Vector[N];
static int power( int a, int b)
{
int res = 1 ;
a = a % mod;
if (a == 0 )
return 0 ;
while (b > 0 )
{
if (b % 2 == 1 )
res = (res * a) % mod;
b = b >> 1 ;
a = (a * a) % mod;
}
return res;
}
static void dfs( int i, boolean []visited)
{
visited[i] = true ;
size++;
for ( int nbr : G[i])
{
if (!visited[nbr])
{
dfs(nbr, visited);
}
}
}
static void totalSequences( int n, int k)
{
boolean []visited = new boolean [n + 1 ];
for ( int i = 1 ; i <= n; i++)
{
if (!visited[i])
{
size = 0 ;
dfs(i, visited);
ans -= power(size, k);
ans += mod;
ans = ans % mod;
}
}
}
static void addEdge( int x, int y, int color)
{
if (color == 0 )
{
G[x].add(y);
G[y].add(x);
}
}
public static void main(String[] args)
{
for ( int i = 0 ; i < G.length; i++)
G[i] = new Vector<Integer>();
int n = 3 ;
int k = 3 ;
ans = power(n, k);
addEdge( 1 , 2 , 1 );
addEdge( 2 , 3 , 1 );
totalSequences(n, k);
System.out.print(ans + "\n" );
}
}
|
Python3
mod = 1e9 + 7
N = 1e5 + 1
G = [ 0 ] * int (N)
def power(a, b):
res = 1
a = a % mod
if a = = 0 :
return 0
while b > 0 :
if b & 1 :
res = (res * a) % mod
b = b >> 1
a = (a * a) % mod
return res
def dfs(i, size, visited):
visited[i] = True
size[ 0 ] + = 1
for nbr in range (G[i]):
if not visited[nbr]:
dfs(nbr, size, visited)
def totalSequences(ans, n, k):
visited = [ False ] * (n + 1 )
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
def addEdge(x, y, color):
if color = = 0 :
G[x].append(y)
G[y].append(x)
if __name__ = = '__main__' :
n = 3
k = 3
ans = [power(n, k)]
addEdge( 1 , 2 , 1 )
addEdge( 2 , 3 , 1 )
totalSequences(ans, n, k)
print ( int (ans[ 0 ]))
|
C#
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;
static List< int > []G =
new List< int >[N];
static int power( int a,
int b)
{
int res = 1;
a = a % mod;
if (a == 0)
return 0;
while (b > 0)
{
if (b % 2 == 1)
res = (res * a) % mod;
b = b >> 1;
a = (a * a) % mod;
}
return res;
}
static void dfs( int i,
bool []visited)
{
visited[i] = true ;
size++;
foreach ( int nbr in G[i])
{
if (!visited[nbr])
{
dfs(nbr, visited);
}
}
}
static void totalSequences( int n,
int k)
{
bool []visited = new bool [n + 1];
for ( int i = 1; i <= n; i++)
{
if (!visited[i])
{
size = 0;
dfs(i, visited);
ans -= power(size, k);
ans += mod;
ans = ans % mod;
}
}
}
static void addEdge( int x,
int y,
int color)
{
if (color == 0)
{
G[x].Add(y);
G[y].Add(x);
}
}
public static void Main(String[] args)
{
for ( int i = 0; i < G.Length; i++)
G[i] = new List< int >();
int n = 3;
int k = 3;
ans = power(n, k);
addEdge(1, 2, 1);
addEdge(2, 3, 1);
totalSequences(n, k);
Console.Write(ans + "\n" );
}
}
|
Javascript
<script>
let mod = (1e9 + 7);
let N = (1e5 + 1);
let size;
let ans;
let G = new Array(N);
function power(a, b)
{
let res = 1;
a = a % mod;
if (a == 0)
return 0;
while (b > 0)
{
if (b % 2 == 1)
res = (res * a) % mod;
b = b >> 1;
a = (a * a) % mod;
}
return res;
}
function dfs(i, visited)
{
visited[i] = true ;
size++;
for (let nbr = 0; nbr < G[i].length; nbr++)
{
if (!visited[G[i][nbr]])
{
dfs(G[i][nbr], visited);
}
}
}
function totalSequences(n, k)
{
let visited = new Array(n + 1);
visited.fill( false );
for (let i = 1; i <= n; i++)
{
if (!visited[i])
{
size = 0;
dfs(i, visited);
ans -= power(size, k);
ans += mod;
ans = ans % mod;
}
}
}
function addEdge(x, y, color)
{
if (color == 0)
{
G[x].push(y);
G[y].push(x);
}
}
for (let i = 0; i < G.length; i++)
G[i] = [];
let n = 3;
let k = 3;
ans = power(n, k);
addEdge(1, 2, 1);
addEdge(2, 3, 1);
totalSequences(n, k);
document.write(ans + "</br>" );
</script>
|
Time Complexity: O(N), Since DFS traversal requires O(Vertices + Edges) == O(N + (N-1)) == O(N) ) complexity.