Connecting employees from different companies
Last Updated :
16 Oct, 2023
A tech fest is buzzing with activity as employees from various companies aim to connect and collaborate. Each connection between employees X and Y is represented as “C X Y” which leads to a merger of their respective companies if they belong to different ones. Initially, N employees represent N companies. You need to implement a system that handles two types of queries efficiently:
- Connection Query (C X Y): Establishes a connection between employees X and Y. If they belong to different companies, their companies merge.
- Query (Q X): Retrieves the size of the company to which employee X belongs.
Examples:
Input: N = 2, Q = 3
Output:
Explanation:
- Query1- Size of the company where Employee 1 belongs to
- Size is 1
- Query2- Connect companies where Employee 1 & Employee 2 belongs to
- Query3- Size of the company where Employee 2 belongs to
Input: N = 3, Q = 3
Output:
Approach: To solve the problem follow the below idea:
The idea is to use the Disjoint-Set Union(DSU) data structure.
The approach using Disjoint-Set Union:
- Let’s treat every employee as a connected component and maintain a Disjoint-Set Union(DSU) data structure.
- Initially, there are components where the i-th component consists of the i-th employee.
- The query for connecting two employees can be handled using the union operation of our Disjoint-Set Union data structure.
- Now to get the size of a component(company) we need to modify the union function a bit.
- For every component let’s store the size of that component. Initially, all the components are of size 1(as only 1 person is there). The size of a component gets updated when it merges with another component and the new size is equal to the sum of the sizes of the components that merged.
Implementation of the above approach:
C++14
#include <iostream>
#include <vector>
using namespace std;
class UnionFind {
private :
vector< int > parent;
vector< int > cnt;
public :
UnionFind( int size)
: parent(size + 1)
, cnt(size + 1)
{
for ( int i = 1; i <= size; ++i) {
parent[i] = i;
cnt[i] = 1;
}
}
int find( int node)
{
if (node == parent[node])
return node;
return parent[node] = find(parent[node]);
}
int totalNodesInSet( int node)
{
return cnt[find(node)];
}
void Union( int a, int b)
{
a = find(a);
b = find(b);
if (a == b)
return ;
parent[b] = a;
cnt[a] += cnt[b];
}
};
int main()
{
int n, q;
n = 3, q = 3;
UnionFind uf(n);
cout << uf.totalNodesInSet(1) << "\n" ;
uf.Union(2, 3);
cout << uf.totalNodesInSet(3) << "\n" ;
return 0;
}
|
Java
import java.util.Arrays;
class UnionFind {
private int [] parent;
private int [] cnt;
public UnionFind( int size) {
parent = new int [size + 1 ];
cnt = new int [size + 1 ];
for ( int i = 1 ; i <= size; ++i) {
parent[i] = i;
cnt[i] = 1 ;
}
}
public int find( int node) {
if (node == parent[node]) {
return node;
}
return parent[node] = find(parent[node]);
}
public int totalNodesInSet( int node) {
return cnt[find(node)];
}
public void union( int a, int b) {
a = find(a);
b = find(b);
if (a == b) {
return ;
}
parent[b] = a;
cnt[a] += cnt[b];
}
}
public class Main {
public static void main(String[] args) {
int n = 3 ;
int q = 3 ;
UnionFind uf = new UnionFind(n);
System.out.println(uf.totalNodesInSet( 1 ));
uf.union( 2 , 3 );
System.out.println(uf.totalNodesInSet( 3 ));
}
}
|
Python
n, queries = map ( int , input ().split())
people = [{ 'parent' : i, 'n' : i, 'size' : 1 } for i in range (n)]
def parent_index(n):
while people[n][ 'parent' ] ! = people[n][ 'n' ]:
people[n][ 'parent' ] = people[people[n][ 'parent' ]][ 'parent' ]
n = people[n][ 'parent' ]
return n
for _ in range (queries):
q = input ().split()
if q[ 0 ] = = 'Q' :
n = int (q[ 1 ]) - 1
print (people[parent_index(n)][ 'size' ])
elif q[ 0 ] = = 'M' :
p1, p2 = parent_index( int (q[ 1 ]) - 1 ), parent_index( int (q[ 2 ]) - 1 )
if p1 ! = p2:
people[p2][ 'parent' ] = people[p1][ 'parent' ]
people[p1][ 'size' ] + = people[p2][ 'size' ]
|
C#
using System;
class UnionFind
{
private int [] parent;
private int [] cnt;
public UnionFind( int size)
{
parent = new int [size + 1];
cnt = new int [size + 1];
for ( int i = 1; i <= size; ++i)
{
parent[i] = i;
cnt[i] = 1;
}
}
public int Find( int node)
{
if (node == parent[node])
{
return node;
}
return parent[node] = Find(parent[node]);
}
public int TotalNodesInSet( int node)
{
return cnt[Find(node)];
}
public void Union( int a, int b)
{
a = Find(a);
b = Find(b);
if (a == b)
{
return ;
}
parent[b] = a;
cnt[a] += cnt[b];
}
}
public class GFG
{
public static void Main( string [] args)
{
int n = 3;
UnionFind uf = new UnionFind(n);
Console.WriteLine(uf.TotalNodesInSet(1));
uf.Union(2, 3);
Console.WriteLine(uf.TotalNodesInSet(3));
}
}
|
Javascript
class GFG {
constructor(size) {
this .parent = Array(size + 1);
this .cnt = Array(size + 1);
for (let i = 1; i <= size; ++i) {
this .parent[i] = i;
this .cnt[i] = 1;
}
}
find(node) {
if (node === this .parent[node]) return node;
return ( this .parent[node] = this .find( this .parent[node]));
}
totalNodesInSet(node) {
return this .cnt[ this .find(node)];
}
union(a, b) {
a = this .find(a);
b = this .find(b);
if (a === b) return ;
this .parent[b] = a;
this .cnt[a] += this .cnt[b];
}
}
function main() {
const n = 3, q = 3;
const uf = new GFG(n);
console.log(uf.totalNodesInSet(1));
uf.union(2, 3);
console.log(uf.totalNodesInSet(3));
}
main();
|
Time Complexity: O(QlogN), N is no of employees, Q is no of queries

Auxiliary Space: O(N), N is no of employees
Share your thoughts in the comments
Please Login to comment...