The Earliest Moment When Everyone Become Friends
Given a group of N people, each having a unique ID value from 0 to (N – 1) and an array arr[] of M elements of the form {U, V, time} representing that the person U will become acquainted with person V at the given time. Let’s say that person U is acquainted with person V if U is friends with V, or U is a friend of someone acquainted with V. The task is to find the earliest time at which every person became acquainted with each other.
Examples:
Input: N = 4, arr[] = {{0, 1, 2}, {1, 2, 3}, {2, 3, 4}}
Output: 4
Explanation: Initially, the number of people are 4, i.e, {0}, {1}, {2}, {3}.
- At time = 2, {0} and {1} became friends. Therefore, the group of acquainted people becomes {0, 1}, {2}, {3}.
- At time = 3, {1} and {2} became friends. Therefore, the group of acquainted people becomes {0, 1, 2}, {3}.
- At time = 4, {2} and {3} became friends. Therefore, the group of acquainted people becomes {0, 1, 2, 3}.
Hence, at time = 4, every person became acquainted with each other.
Input: N = 6, arr[] = {{0, 1, 4}, {3, 4, 5}, {2, 3, 14}, {1, 5, 24}, {2, 4, 12}, {0, 3, 42}, {1, 2, 41}, {4, 5, 11}}
Output: 24
Approach: The given problem can be solved using the Disjoint Set Union Data Structure. The idea is to perform the union operations between people in order of the increasing value of time. The required answer will be the time when all people belong to the same set. Follow the steps below to solve the given problem:
- Implement the Disjoint Set Union Data Structure with the union and findSet functions according to the algorithm discussed here.
- Initialize a variable time, which stores the value of the current timestamp of the DSU.
- Sort the given array arr[] in increasing order of time.
- Traverse the given array arr[] using variable i, and perform union operation between (Ui, Vi) and update the current timestamp to timei if Ui and Vi belong to the different sets.
- If the total number of sets after completely traversing through the array arr[] is 1, return the value of the variable time, else return -1.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include "bits/stdc++.h" using namespace std; // Implementation of DSU class UnionFind { vector< int > parent, rank; // Stores the current timestamp int time ; // Stores the count of current sets int count; public : // Constructor to create and // initialize sets of N items UnionFind( int N) : parent(N), rank(N), count(N) { time = 0; // Creates N single item sets for ( int i = 0; i < N; i++) { parent[i] = i; rank[i] = 1; } } // Function to find the set of // given item node int find( int node) { if (node == parent[node]) return node; return parent[node] = find(parent[node]); } // Function to perform the union of // two sets represented by u and v, // and update the value of time void performUnion( int u, int v, int updatedTime) { if (count == 1) return ; // Find current sets of u and v int rootX = find(u); int rootY = find(v); if (rootX != rootY) { // Put smaller ranked item under // bigger ranked item if ranks // are different if (rank[rootX] < rank[rootY]) { parent[rootX] = rootY; } else if (rank[rootX] > rank[rootY]) { parent[rootY] = rootX; } else { parent[rootX] = rootY; rank[rootY] += 1; } // Update the value of the // current timestamp time = updatedTime; // Update the value of // set count count--; } } // Function to return current // set count int getCount() { return count; } // Function to return current // time stamp int getTime() { return time ; } }; // Comparator function to sort the array // in increasing order of 3rd element bool cmp(vector< int >& A, vector< int >& B) { return A[2] <= B[2]; } // Function to find the earliest time when // everyone became friends to each other int earliestTime(vector<vector< int > >& arr, int N) { // Sort array arr[] in increasing order sort(arr.begin(), arr.end(), cmp); // Initialize a DSU with N elements UnionFind unionFind(N); // Iterate over array arr[] perform // union operation for each element for ( auto & it : arr) { // Perform union operation on // it[0] and it[1] and update // timestamp to it[2] unionFind.performUnion( it[0], it[1], it[2]); } // Return Answer if (unionFind.getCount() == 1) { return unionFind.getTime(); } else { return -1; } } // Driver Code int main() { int N = 6; vector<vector< int > > arr = { { 0, 1, 4 }, { 3, 4, 5 }, { 2, 3, 14 }, { 1, 5, 24 }, { 2, 4, 12 }, { 0, 3, 42 }, { 1, 2, 41 }, { 4, 5, 11 } }; cout << earliestTime(arr, N); return 0; } |
Javascript
// JavaScript code for the above approach // Implementation of DSU class UnionFind { constructor(N) { this .parent = new Array(N); this .rank = new Array(N); this .time = 0; this .count = N; // Creates N single item sets for (let i = 0; i < N; i++) { this .parent[i] = i; this .rank[i] = 1; } } // Function to find the set of // given item node find(node) { if (node === this .parent[node]) { return node; } return ( this .parent[node] = this .find( this .parent[node])); } // Function to perform the union of // two sets represented by u and v, // and update the value of time performUnion(u, v, updatedTime) { if ( this .count === 1) { return ; } // Find current sets of u and v let rootX = this .find(u); let rootY = this .find(v); if (rootX !== rootY) { // Put smaller ranked item under // bigger ranked item if ranks // are different if ( this .rank[rootX] < this .rank[rootY]) { this .parent[rootX] = rootY; } else if ( this .rank[rootX] > this .rank[rootY]) { this .parent[rootY] = rootX; } else { this .parent[rootX] = rootY; this .rank[rootY] += 1; } // Update the value of the // current timestamp this .time = updatedTime; // Update the value of // set count this .count--; } } // Function to return current // set count getCount() { return this .count; } // Function to return current // time stamp getTime() { return this .time; } } // Comparator function to sort the array // in increasing order of 3rd element function cmp(A, B) { return A[2] - B[2]; } // Function to find the earliest time when // everyone became friends to each other function earliestTime(arr, N) { // Sort array arr[] in increasing order arr.sort(cmp); // Initialize a DSU with N elements let unionFind = new UnionFind(N); // Iterate over array arr[] perform // union operation for each element for (let it of arr) { // Perform union operation on // it[0] and it[1] and update // timestamp to it[2] unionFind.performUnion(it[0], it[1], it[2]); } // Return Answer if (unionFind.getCount() === 1) { return unionFind.getTime(); } else { return -1; } } // Driver Code let N = 6; let arr = [ [0, 1, 4], [3, 4, 5], [2, 3, 14], [1, 5, 24], [2, 4, 12], [0, 3, 42], [1, 2, 41], [4, 5, 11], ]; console.log(earliestTime(arr, N)); // This code is contributed by Potta Lokesh. |
24
Time Complexity: O(N)
Auxiliary Space: O(N)
Please Login to comment...