Given N cities number from 0 to N – 1. These are connected by M bidirectional roads. The ith road connects two distinct cities Edge[i][0] and Edge[i][1]. We are also given a string s, where s[i] will represent the colour associated with ith city. Each city will have 1 color only. Given Q queries, in the ith query, you are given 3 distinct colours query[i][0], query[i][1], and query[i][2]. For each query return “YES” if there exists a path such that only the city with these three colors comes in the way else return “NO“.
Examples:
Input: N = 6, M = 7, Q = 3, S = “abdebc” , Edge[][] = {{0, 1}, {0, 2}, {1, 3}, {1, 4}, {1, 2}, {2, 4}, {4,5}}, Query[] = {“abc”,”aec”,”azc”} Output: YES NO NO Explanation:
- Query 1: “abc” there exists a path 0 -> 1 -> 4 -> 5 which only consists of colours a, b and c.
- Query 2: “aec” There is no such path which will contain only a,e,c colours.
- Query 3: “azc” There is no such path which will contain only a,z,c colours.
Approach: This can be solved with the following idea:
Using Depth First Search technique, we can find path of colours possible from each edge. Store each path in dp. While answering the queries, we can find all possible combination formed from 3 colours. Check whether through dp it is possible or not.
Below are the steps to solve this problem:
- Create an adjacency list adj[] through edges.
- Initialize a dp[26][26][26], as there are 3 different colors.
- Iterate in vertices and mark that node visited.
- For a node iterate through other nodes, which can be reached.
- Make a set of colors in the set and store the value in DP.
- Iterate in queries:
- For each colours set, make combinations and check whether it exist in dp
- If exist, Return Yes
- Otherwise, No
- Store the answers in ans vector.
- Return ans.
Below is the implementation of the code:
C++
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
void dfs( int node, unordered_map< int , vector< int > >& adj,
string& col, set< char >& set, vector< bool >& vis)
{
vis[node] = 1;
for ( auto nbr : adj[node]) {
if (!vis[nbr] && col[nbr] == col[node]) {
dfs(nbr, adj, col, set, vis);
}
else {
set.insert(col[nbr]);
}
}
}
vector<string> solve( int N, int M, int Q, string col,
vector<vector< int > >& Edge,
vector<string>& query)
{
vector< bool > vis(N, false );
int dp[26][26][26] = { 0 };
unordered_map< int , vector< int > > adj;
for ( auto i : Edge) {
adj[i[0]].push_back(i[1]);
adj[i[1]].push_back(i[0]);
}
for ( int i = 0; i < N; i++) {
if (!vis[i]) {
set< char > set;
dfs(i, adj, col, set, vis);
for ( auto it1 : set) {
for ( auto it2 : set) {
dp[it1 - 'a' ][col[i] - 'a' ][it2 - 'a' ]
= 1;
}
}
}
}
vector<string> ans;
for ( auto str : query) {
int a = str[0] - 'a' ;
int b = str[1] - 'a' ;
int c = str[2] - 'a' ;
if (dp[a][b] || dp[a][b] || dp[b][a]
|| dp[b][a] || dp[a][b] || dp[b][a])
ans.push_back("YES");
else
ans.push_back("NO");
}
return ans;
}
int main()
{
int N = 6;
int M = 7;
int Q = 3;
string col = "abdebc";
vector<vector< int > > Edge
= { { 0, 1 }, { 0, 2 }, { 1, 3 }, { 1, 4 },
{ 1, 2 }, { 2, 4 }, { 4, 5 } };
vector<string> query = { "abc", "aec", "azc" };
vector<string> ans = solve(N, M, Q, col, Edge, query);
for ( auto a : ans) {
cout << a << " ";
}
return 0;
}
|
Java
import java.util.*;
public class Main {
static void dfs( int node, HashMap<Integer, ArrayList<Integer>> adj,
String col, HashSet<Character> set, boolean [] vis) {
vis[node] = true ;
for ( int nbr : adj.get(node)) {
if (!vis[nbr] && col.charAt(nbr) == col.charAt(node)) {
dfs(nbr, adj, col, set, vis);
} else {
set.add(col.charAt(nbr));
}
}
}
static ArrayList<String> solve( int N, int M, int Q, String col,
int [][] Edge, String[] query) {
boolean [] vis = new boolean [N];
int [][][] dp = new int [ 26 ][ 26 ][ 26 ];
HashMap<Integer, ArrayList<Integer>> adj = new HashMap<>();
for ( int i = 0 ; i < N; i++) {
adj.put(i, new ArrayList<>());
}
for ( int [] i : Edge) {
adj.get(i[ 0 ]).add(i[ 1 ]);
adj.get(i[ 1 ]).add(i[ 0 ]);
}
for ( int i = 0 ; i < N; i++) {
if (!vis[i]) {
HashSet<Character> set = new HashSet<>();
dfs(i, adj, col, set, vis);
for ( char it1 : set) {
for ( char it2 : set) {
dp[it1 - 'a' ][col.charAt(i) - 'a' ][it2 - 'a' ] = 1 ;
}
}
}
}
ArrayList<String> ans = new ArrayList<>();
for (String str : query) {
int a = str.charAt( 0 ) - 'a' ;
int b = str.charAt( 1 ) - 'a' ;
int c = str.charAt( 2 ) - 'a' ;
if (dp[a][b] == 1 || dp[a][b] == 1 || dp[b][a] == 1 ||
dp[b][a] == 1 || dp[a][b] == 1 || dp[b][a] == 1 ) {
ans.add( "YES" );
} else {
ans.add( "NO" );
}
}
return ans;
}
public static void main(String[] args) {
int N = 6 ;
int M = 7 ;
int Q = 3 ;
String col = "abdebc" ;
int [][] Edge = { { 0 , 1 }, { 0 , 2 }, { 1 , 3 }, { 1 , 4 }, { 1 , 2 }, { 2 , 4 }, { 4 , 5 } };
String[] query = { "abc" , "aec" , "azc" };
ArrayList<String> ans = solve(N, M, Q, col, Edge, query);
for (String a : ans) {
System.out.print(a + " " );
}
}
}
|
Python3
from collections import defaultdict
def dfs(node, adj, col, color_set, vis):
vis[node] = 1
for nbr in adj[node]:
if not vis[nbr] and col[nbr] = = col[node]:
dfs(nbr, adj, col, color_set, vis)
else :
color_set.add(col[nbr])
def solve(N, M, Q, col, Edge, query):
vis = [ False ] * N
dp = [[[ 0 ] * 26 for _ in range ( 26 )] for _ in range ( 26 )]
adj = defaultdict( list )
for i in Edge:
adj[i[ 0 ]].append(i[ 1 ])
adj[i[ 1 ]].append(i[ 0 ])
for i in range (N):
if not vis[i]:
color_set = set ()
dfs(i, adj, col, color_set, vis)
for it1 in color_set:
for it2 in color_set:
dp[ ord (it1) - ord ( 'a' )][ ord (col[i]) - ord ( 'a' )][ ord (it2) - ord ( 'a' )] = 1
ans = []
for string in query:
a = ord (string[ 0 ]) - ord ( 'a' )
b = ord (string[ 1 ]) - ord ( 'a' )
c = ord (string[ 2 ]) - ord ( 'a' )
if dp[a][b] or dp[a][b] or dp[b][a] or dp[b][a] or dp[a][b] or dp[b][a]:
ans.append( "YES" )
else :
ans.append( "NO" )
return ans
if __name__ = = "__main__" :
N = 6
M = 7
Q = 3
col = "abdebc"
Edge = [[ 0 , 1 ], [ 0 , 2 ], [ 1 , 3 ], [ 1 , 4 ], [ 1 , 2 ], [ 2 , 4 ], [ 4 , 5 ]]
query = [ "abc" , "aec" , "azc" ]
ans = solve(N, M, Q, col, Edge, query)
for a in ans:
print (a, end = " " )
|
C#
using System;
using System.Collections.Generic;
public class GFG {
static void DFS( int node,
Dictionary< int , List< int > > adj,
ref string col, ref HashSet< char > set ,
ref List< bool > vis)
{
vis[node] = true ;
foreach ( var nbr in adj[node])
{
if (!vis[nbr] && col[nbr] == col[node]) {
DFS(nbr, adj, ref col, ref set , ref vis);
}
else {
set .Add(col[nbr]);
}
}
}
static List< string > Solve( int N, int M, int Q,
string col,
List<List< int > > Edge,
List< string > query)
{
List< bool > vis = new List< bool >( new bool [N]);
int [, , ] dp = new int [26, 26, 26];
Dictionary< int , List< int > > adj
= new Dictionary< int , List< int > >();
foreach ( var i in Edge)
{
if (!adj.ContainsKey(i[0]))
adj[i[0]] = new List< int >();
if (!adj.ContainsKey(i[1]))
adj[i[1]] = new List< int >();
adj[i[0]].Add(i[1]);
adj[i[1]].Add(i[0]);
}
for ( int i = 0; i < N; i++) {
if (!vis[i]) {
HashSet< char > set = new HashSet< char >();
DFS(i, adj, ref col, ref set , ref vis);
foreach ( var it1 in set )
{
foreach ( var it2 in set )
{
dp[it1 - 'a' , col[i] - 'a' ,
it2 - 'a' ]
= 1;
}
}
}
}
List< string > ans = new List< string >();
foreach ( var str in query)
{
int a = str[0] - 'a' ;
int b = str[1] - 'a' ;
int c = str[2] - 'a' ;
if (dp[a, b, c] != 0 || dp[a, c, b] != 0
|| dp[b, a, c] != 0 || dp[b, c, a] != 0
|| dp != 0 || dp != 0)
ans.Add( "YES" );
else
ans.Add( "NO" );
}
return ans;
}
public static void Main()
{
int N = 6;
int M = 7;
int Q = 3;
string col = "abdebc" ;
List<List< int > > Edge = new List<List< int > >{
new List< int >{ 0, 1 }, new List< int >{ 0, 2 },
new List< int >{ 1, 3 }, new List< int >{ 1, 4 },
new List< int >{ 1, 2 }, new List< int >{ 2, 4 },
new List< int >{ 4, 5 }
};
List< string > query
= new List< string >{ "abc" , "aec" , "azc" };
List< string > ans = Solve(N, M, Q, col, Edge, query);
foreach ( var a in ans) { Console.Write(a + " " ); }
}
}
|
Javascript
function DFS(node, adj, col, colorSet, vis) {
vis[node] = true ;
const neighbors = Array.from(adj.get(node) || []);
for (const nbr of neighbors) {
if (!vis[nbr] && col[nbr] === col[node]) {
DFS(nbr, adj, col, colorSet, vis);
} else {
colorSet.add(col[nbr]);
}
}
}
function Solve(N, M, Q, col, Edge, query) {
const vis = Array(N).fill( false );
const dp = Array.from({ length: 26 }, () =>
Array.from({ length: 26 }, () => Array(26).fill(0))
);
const adj = new Map();
for (const i of Edge) {
if (!adj.has(i[0])) adj.set(i[0], []);
if (!adj.has(i[1])) adj.set(i[1], []);
adj.get(i[0]).push(i[1]);
adj.get(i[1]).push(i[0]);
}
for (let i = 0; i < N; i++) {
if (!vis[i]) {
const colorSet = new Set();
DFS(i, adj, col, colorSet, vis);
for (const it1 of colorSet) {
for (const it2 of colorSet) {
dp[it1.charCodeAt() - 'a' .charCodeAt()][col[i].charCodeAt() - 'a' .charCodeAt()][it2.charCodeAt() - 'a' .charCodeAt()] = 1;
}
}
}
}
const ans = [];
for (const str of query) {
const a = str.charCodeAt(0) - 'a' .charCodeAt();
const b = str.charCodeAt(1) - 'a' .charCodeAt();
const c = str.charCodeAt(2) - 'a' .charCodeAt();
if (dp[a][b] !== 0 || dp[a][b] !== 0 || dp[b][a] !== 0 || dp[b][a] !== 0 || dp[a][b] !== 0 || dp[b][a] !== 0) ans.push( "YES" );
else ans.push( "NO" );
}
return ans;
}
const N = 6;
const M = 7;
const Q = 3;
const col = "abdebc" ;
const Edge = [
[0, 1], [0, 2], [1, 3],
[1, 4], [1, 2], [2, 4],
[4, 5]
];
const query = [ "abc" , "aec" , "azc" ];
const ans = Solve(N, M, Q, col, Edge, query);
console.log(ans.join( " " ));
|
Time Complexity: O(N * M + Q) Auxiliary Space: O(N)
|