Island Connectivity for Q queries
Last Updated :
26 Oct, 2023
Given an integer N denoting the number of disconnected islands from 1 to N. You have to process Q queries of the following types:
- Type 1 query: 0 u v => Connect islands u and v
- Type 2 query: 1 u v => Print “YES” if islands u and v are connected otherwise print “NO”
Note: The connection between the islands follows transitive property.
Examples:
Input: N = 5, Q = 8, Queries = [[0 1 2], [1 2 1], [0 3 4], [1 1 4], [0 3 2], [1 2 3], [1 1 4], [1 1 5]]
Output: [YES, NO, YES, YES, NO]
Explanation: Initially islands = {1}, {2}, {3}, {4}, {5}
- query[0] island ‘1’ and island ‘2’ merge => {1, 2}, {3}, {4}, {5}
- query[1] => print YES as island 2 and island 1 is connected
- query[2] island ‘3’ and island ‘4’ merge => {1, 2}, {3, 4}, {5}
- query[3] => print NO as island 1 and island 4 are not connected.
- query[4] island ‘3’ and island ‘2’ merge => {1, 2, 3, 4}, {5}
- query[5] => print YES as island 2 and island 3 are connected.
- query[6] => print YES as island 1 and island 4 are connected.
- query[7] => print NO as island 1 and island 5 are not connected.
Input: N = 3, Q = 3, Queries = [[1 1 2], [1 2 3], [1 1 3]]
Output: [NO, NO, NO]
Explanation: Clearly there is no query of Type 1, hence all the islands remain disconnected.
Approach: We can solve this problem using the Disjoint Set Union (DSU) data structure:
Observations:
If we break down this question to a smaller scale, we observe that for each Type 1 query we have to put two disjoint island into a same set and for each query of Type 2 we have to know whether the two island belong to same set or are disjoint to each other. What data structure can be used to tackle this situation?
YES you guessed it right, this problem revolves around the construction of a Union and find functions of DSU.
- For Type 1 query: Use Union() operation of DSU to Merge the two disjoint islands u and v.
- For Type 2 query: Use Find() function to know whether the two island u and v have same parent or not.
Follow the steps to solve the problem:
- Construct the Union() and Find() functions of DSU.
- Initialize the Parent[] array for each island ‘i’ such that parent[i]=i.
- Now process each query one by one as per below condition
- If Type 1 query: Union(island u, island v)
- If Type 2 query: Print Yes if Find(island u) == Find(island v), otherwise print NO.
Below is the code for the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int parent[100001];
int size[100001];
void make( int i)
{
parent[i] = i;
size[i] = 1;
}
int find( int v)
{
if (v == parent[v])
return v;
return parent[v] = find(parent[v]);
}
void Union( int a, int b)
{
a = find(a);
b = find(b);
if (a != b) {
if (size[a] < size[b])
swap(a, b);
parent[b] = a;
size[a] += size[b];
}
}
int main()
{
int N = 5;
int Q = 8;
vector<vector< int > > Queries
= { { 0, 1, 2 }, { 1, 2, 1 }, { 0, 3, 4 },
{ 1, 1, 4 }, { 0, 3, 2 }, { 1, 2, 3 },
{ 1, 1, 4 }, { 1, 1, 5 } };
for ( int i = 1; i <= N; i++)
make(i);
for ( auto e : Queries) {
int type, u, v;
type = e[0];
u = e[1];
v = e[2];
if (type) {
if (find(u) == find(v)) {
cout << "Yes" ;
}
else
cout << "No" ;
cout << endl;
}
else
Union(u, v);
}
}
|
Java
import java.util.*;
class GFG {
static int [] parent = new int [ 100001 ];
static int [] size = new int [ 100001 ];
static void make( int i)
{
parent[i] = i;
size[i] = 1 ;
}
static int find( int v)
{
if (v == parent[v])
return v;
return parent[v] = find(parent[v]);
}
static void Union( int a, int b)
{
a = find(a);
b = find(b);
if (a != b) {
if (size[a] < size[b]) {
int temp = a;
a = b;
b = temp;
}
parent[b] = a;
size[a] += size[b];
}
}
public static void main(String[] args)
{
int N = 5 ;
int Q = 8 ;
int [][] Queries
= { { 0 , 1 , 2 }, { 1 , 2 , 1 }, { 0 , 3 , 4 },
{ 1 , 1 , 4 }, { 0 , 3 , 2 }, { 1 , 2 , 3 },
{ 1 , 1 , 4 }, { 1 , 1 , 5 } };
for ( int i = 1 ; i <= N; i++) {
make(i);
}
for ( int [] e : Queries) {
int type, u, v;
type = e[ 0 ];
u = e[ 1 ];
v = e[ 2 ];
if (type == 1 ) {
if (find(u) == find(v)) {
System.out.print( "Yes" );
}
else {
System.out.print( "No" );
}
System.out.println();
}
else
Union(u, v);
}
}
}
|
Python3
def make(i):
parent[i] = i
size[i] = 1
def find(v):
if v = = parent[v]:
return v
parent[v] = find(parent[v])
return parent[v]
def Union(a, b):
a = find(a)
b = find(b)
if a ! = b:
if size[a] < size[b]:
a, b = b, a
parent[b] = a
size[a] + = size[b]
N = 5
Q = 8
Queries = [
[ 0 , 1 , 2 ], [ 1 , 2 , 1 ], [ 0 , 3 , 4 ],
[ 1 , 1 , 4 ], [ 0 , 3 , 2 ], [ 1 , 2 , 3 ],
[ 1 , 1 , 4 ], [ 1 , 1 , 5 ]
]
parent = [ 0 ] * (N + 1 )
size = [ 0 ] * (N + 1 )
for i in range ( 1 , N + 1 ):
make(i)
for e in Queries:
type , u, v = e
if type :
if find(u) = = find(v):
print ( "Yes" )
else :
print ( "No" )
else :
Union(u, v)
|
C#
using System;
using System.Collections.Generic;
class Program
{
static int [] parent = new int [100001];
static int [] size = new int [100001];
static void Make( int i)
{
parent[i] = i;
size[i] = 1;
}
static int Find( int v)
{
if (v == parent[v])
return v;
return parent[v] = Find(parent[v]);
}
static void Union( int a, int b)
{
a = Find(a);
b = Find(b);
if (a != b)
{
if (size[a] < size[b])
Swap( ref a, ref b);
parent[b] = a;
size[a] += size[b];
}
}
static void Swap( ref int a, ref int b)
{
int temp = a;
a = b;
b = temp;
}
static void Main( string [] args)
{
int N = 5;
List< int []> Queries = new List< int []>
{
new int [] { 0, 1, 2 }, new int [] { 1, 2, 1 }, new int [] { 0, 3, 4 },
new int [] { 1, 1, 4 }, new int [] { 0, 3, 2 }, new int [] { 1, 2, 3 },
new int [] { 1, 1, 4 }, new int [] { 1, 1, 5 }
};
for ( int i = 1; i <= N; i++)
Make(i);
foreach ( var e in Queries)
{
int type = e[0];
int u = e[1];
int v = e[2];
if (type == 1)
{
if (Find(u) == Find(v))
{
Console.WriteLine( "Yes" );
}
else
{
Console.WriteLine( "No" );
}
}
else
{
Union(u, v);
}
}
}
}
|
Javascript
let parent = new Array(100001);
let size = new Array(100001);
function make(i) {
parent[i] = i;
size[i] = 1;
}
function find(v) {
if (v == parent[v])
return v;
return parent[v] = find(parent[v]);
}
function Union(a, b) {
a = find(a);
b = find(b);
if (a != b) {
if (size[a] < size[b])
swap(a, b);
parent[b] = a;
size[a] += size[b];
}
}
function main() {
let N = 5;
let Q = 8;
let Queries = [
[0, 1, 2],
[1, 2, 1],
[0, 3, 4],
[1, 1, 4],
[0, 3, 2],
[1, 2, 3],
[1, 1, 4],
[1, 1, 5]
];
for (let i = 1; i <= N; i++) {
make(i);
}
for (let e of Queries) {
let type, u, v;
type = e[0];
u = e[1];
v = e[2];
if (type) {
if (find(u) == find(v)) {
console.log( "Yes" );
}
else {
console.log( "No" );
}
}
else {
Union(u, v);
}
}
}
main()
|
Complexity Analysis:
- Time Complexity: max(N, Q) where N is the number of Islands and Q is total number of queries
- Auxiliary Space: O(N) for the parent array
Share your thoughts in the comments
Please Login to comment...