Given an undirected weighted graph G consisting of N vertices and M edges, and two arrays Edges[][2] and Weight[] consisting of M edges of the graph and weights of each edge respectively, the task is to find the maximum product of any two vertices of the largest connected component of the graph, formed by connecting all edges with the same weight.
Examples:
Input: N = 4, Edges[][] = {{1, 2}, {1, 2}, {2, 3}, {2, 3}, {2, 4}}, Weight[] = {1, 2, 1, 3, 3}
Output: 12
Explanation:
- Components of edges of weight 1, 1 ? 2 ? 3. The maximum product of any two vertices of this component is 6.
- Components of edges of weight 2, 1 ? 2. The maximum product of any two vertices of this component is 2.
- Components of edges of weight 3, 4 ? 2 ? 3. The maximum product of any two vertices of this component is 12.
Therefore, the maximum product among all the connected components of size 3 (which is maximum) is 12.
Input: N = 5, Edges[][] = {{1, 5}, {2, 5}, {3, 5}, {4, 5}, {1, 2}, {2, 3}, {3, 4}}, Weight[] = {1, 1, 1, 1, 2, 2, 2}
Output: 20
Approach: The given problem can be solved by performing the DFS traversal on the given graph and maximize the product of the first and second maximum node for all the connected components of the same weight. Follow the steps below to solve the problem:
- Store all the edges corresponding to all the unique weight in a map M.
- Initialize a variable, say res as 0 to store the maximum product of any two nodes of the connected components of the same weights.
- Traverse the map and for each key as weight create a graph by connecting all the edges mapped with the particular weight and perform the following operations:
- Find the value of the maximum(say M1) and the second maximum(say M2) node’s value and the size of all the connected components of the graph by performing the DFS Traversal on the created graph.
- Update the value of res to the maximum of res, M1, and M2 if the size of the currently connected components is at least the largest size connected component found previously.
- After completing the above steps, print the value of res as the maximum product.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Stores the first and second largest // element in a connected component int Max, sMax; // Stores the count of nodes // in the connected components int cnt = 0; // Function to perform DFS Traversal // on a given graph and find the first // and the second largest elements void dfs( int u, int N, vector< bool >& vis, vector<vector< int > >& adj) { // Update the maximum value if (u > Max) { sMax = Max; Max = u; } // Update the second max value else if (u > sMax) { sMax = u; } // Increment size of component cnt++; // Mark current node visited vis[u] = true ; // Traverse the adjacent nodes for ( auto to : adj[u]) { // If to is not already visited if (!vis[to]) { dfs(to, N, vis, adj); } } return ; } // Function to find the maximum // product of a connected component int MaximumProduct( int N, vector<pair< int , int > > Edge, vector< int > wt) { // Stores the count of edges int M = wt.size(); // Stores all the edges mapped // with a particular weight unordered_map< int , vector<pair< int , int > > > mp; // Update the map mp for ( int i = 0; i < M; i++) mp[wt[i]].push_back(Edge[i]); // Stores the result int res = 0; // Traverse the map mp for ( auto i : mp) { // Stores the adjacency list vector<vector< int > > adj(N + 1); // Stores the edges of // a particular weight vector<pair< int , int > > v = i.second; // Traverse the vector v for ( int j = 0; j < v.size(); j++) { int U = v[j].first; int V = v[j].second; // Add an edge adj[U].push_back(V); adj[V].push_back(U); } // Stores if a vertex // is visited or not vector< bool > vis(N + 1, 0); // Stores the maximum // size of a component int cntMax = 0; // Iterate over the range [1, N] for ( int u = 1; u <= N; u++) { // Assign Max, sMax, count = 0 Max = sMax = cnt = 0; // If vertex u is not visited if (!vis[u]) { dfs(u, N, vis, adj); // If cnt is greater // than cntMax if (cnt > cntMax) { // Update the res res = Max * sMax; cntMax = cnt; } // If already largest // connected component else if (cnt == cntMax) { // Update res res = max(res, Max * sMax); } } } } // Return res return res; } // Driver Code int main() { int N = 5; vector<pair< int , int > > Edges = { { 1, 2 }, { 2, 5 }, { 3, 5 }, { 4, 5 }, { 1, 2 }, { 2, 3 }, { 3, 4 } }; vector< int > Weight = { 1, 1, 1, 1, 2, 2, 2 }; cout << MaximumProduct(N, Edges, Weight); return 0; } |
Java
// Java code to implement the approach import java.util.*; class GFG { // Stores the first and second largest // element in a connected component static int Max, sMax, cnt; // Function to perform DFS Traversal // on a given graph and find the first // and the second largest elements static void dfs( int u, int N, List<Boolean> vis, List<List<Integer> > adj) { // Update the maximum value if (u > Max) { sMax = Max; Max = u; } // Update the second max value else if (u > sMax) { sMax = u; } // Increment size of component cnt++; // Mark current node visited vis.set(u, true ); // Traverse the adjacent nodes for ( int i = 0 ; i < adj.get(u).size(); i++) { int to = adj.get(u).get(i); // If to is not already visited if (!vis.get(to)) { dfs(to, N, vis, adj); } } } // Function to find the maximum // product of a connected component static int MaximumProduct( int N, List< int []> Edge, List<Integer> wt) { int M = wt.size(); // Stores all the edges mapped // with a particular weight Map<Integer, List< int []> > mp = new HashMap<>(); for ( int i = 0 ; i < M; i++) { if (!mp.containsKey(wt.get(i))) { mp.put(wt.get(i), new ArrayList<>()); } mp.get(wt.get(i)).add(Edge.get(i)); } List<Integer> keys = new ArrayList<>(mp.keySet()); Collections.sort(keys, Collections.reverseOrder()); // Stores the result int res = 0 ; // Traverse the map mp for (Integer i : keys) { List<List<Integer> > adj = new ArrayList<>(); for ( int j = 0 ; j <= N; j++) adj.add( new ArrayList<>()); // Stores the edges of // a particular weight List< int []> v = mp.get(i); // Traverse the vector v for ( int j = 0 ; j < v.size(); j++) { int U = v.get(j)[ 0 ]; int V = v.get(j)[ 1 ]; adj.get(U).add(V); adj.get(V).add(U); } // Stores the maximum // size of a component List<Boolean> vis = new ArrayList<>(); for ( int j = 0 ; j <= N; j++) vis.add( false ); int cntMax = 0 ; for ( int u = 1 ; u <= N; u++) { // Assign Max, sMax, count = 0 Max = 0 ; sMax = 0 ; cnt = 0 ; // If vertex u is not visited if (!vis.get(u)) { dfs(u, N, vis, adj); // If cnt is greater // than cntMax if (cnt > cntMax) { // Update the res res = Max * sMax; cntMax = cnt; } // If already largest // connected component else if (cnt == cntMax) { // Update res res = Math.max(res, Max * sMax); } } } } return res; } // Driver code public static void main(String[] args) { int N = 5 ; List< int []> Edges = new ArrayList<>(); Edges.add( new int []{ 1 , 2 }); Edges.add( new int []{ 2 , 5 }); Edges.add( new int []{ 3 , 5 }); Edges.add( new int []{ 4 , 5 }); Edges.add( new int []{ 1 , 2 }); Edges.add( new int []{ 2 , 3 }); Edges.add( new int []{ 3 , 4 }); List<Integer> Weights = Arrays.asList( 1 , 1 , 1 , 1 , 2 , 2 , 2 ); System.out.println(MaximumProduct(N, Edges, Weights)); } } // This code is contributed by phasing17 |
Python3
# Function to perform DFS Traversal # on a given graph and find the first # and the second largest elements def dfs(u, N, vis, adj): global Max global sMax global cnt # Update the maximum value if u > Max : sMax = Max Max = u # Update the second max value elif u > sMax: sMax = u # Increment size of component cnt + = 1 # Mark current node visited vis[u] = True # Traverse the adjacent nodes for to in adj[u]: # If to is not already visited if not vis[to]: dfs(to, N, vis, adj) def maximumProduct(N, Edge, wt): # Stores the count of edges M = len (wt) # Stores all the edges mapped # with a particular weight mp = {} # Update the map mp for i in range (M): weight = wt[i] if weight not in mp: mp[weight] = [Edge[i]] else : mp[weight].append(Edge[i]) # Stores the result res = 0 keys = list (mp.keys()) keys.sort(reverse = True ) # Traverse the map mp for key in keys: weight = mp[key] # Stores the adjacency list adj = [ [] for _ in range (N + 1 )] # Stores the edges of # a particular weight v = weight # Traverse the vector v for j in range ( len (v)): U, V = v[j] # Add an edge adj[U].append(V) adj[V].append(U) # Stores if a vertex # is visited or not vis = [ False for _ in range (N + 1 )] # Stores the maximum # size of a component cntMax = 0 # Iterate over the range [1, N] for u in range ( 1 , N + 1 ): global Max global sMax global cnt # Assign Max, sMax, count = 0 Max = 0 sMax = 0 cnt = 0 ; # If vertex u is not visited if not vis[u]: dfs(u, N, vis, adj); # If cnt is greater # than cntMax if cnt > cntMax: # Update the res res = Max * sMax; cntMax = cnt; # If already largest # connected component elif cnt = = cntMax: # Update res res = max (res, Max * sMax); return res # driver code N = 5 ; Edges = [[ 1 , 2 ], [ 2 , 5 ], [ 3 , 5 ], [ 4 , 5 ], [ 1 , 2 ], [ 2 , 3 ], [ 3 , 4 ]]; Weight = [ 1 , 1 , 1 , 1 , 2 , 2 , 2 ]; print (maximumProduct(N, Edges, Weight)); # This code is contributed by phasing17. |
Javascript
// JavaScript implementation of the approach function dfs(u, N, vis, adj) { // Update the maximum value if (u > Max) { sMax = Max; Max = u; } // Update the second max value else if (u > sMax) { sMax = u; } // Increment size of component cnt++; // Mark current node visited vis[u] = true ; // Traverse the adjacent nodes for (const to of adj[u]) { // If to is not already visited if (!vis[to]) { dfs(to, N, vis, adj); } } } function maximumProduct(N, Edge, wt) { // Stores the count of edges const M = wt.length; // Stores all the edges mapped // with a particular weight const mp = {}; // Update the map mp for (let i = 0; i < M; i++) { const weight = wt[i]; if (!mp.hasOwnProperty(weight)) { mp[weight] = [Edge[i]]; } else { mp[weight].push(Edge[i]); } } // Stores the result let res = 0; let keys = Object.keys(mp) keys.sort( function (a, b) { return -a + b; }) // Traverse the map mp for (const key of keys) { let weight = mp[key] // Stores the adjacency list const adj = new Array(N + 1); for ( var i = 0; i <= N; i++) adj[i] = [] // Stores the edges of // a particular weight const v = weight; // Traverse the vector v for (let j = 0; j < v.length; j++) { const U = v[j][0]; const V = v[j][1]; // Add an edge let l1 = adj[U] l1.push(V) adj[U] = l1 let l2 = adj[V] l2.push(U) adj[V] = l2 } // Stores if a vertex // is visited or not const vis = new Array(N + 1).fill( false ) // Stores the maximum // size of a component let cntMax = 0; // Iterate over the range [1, N] for (let u = 1; u <= N; u++) { // Assign Max, sMax, count = 0 Max = 0 sMax = 0 cnt = 0; // If vertex u is not visited if (!vis[u]) { dfs(u, N, vis, adj); // If cnt is greater // than cntMax if (cnt > cntMax) { // Update the res res = Max * sMax; cntMax = cnt; } // If already largest // connected component else if (cnt == cntMax) { // Update res res = Math.max(res, Max * sMax); } } } } return res } // driver code const N = 5; const Edges = [[1, 2], [2, 5], [3, 5], [4, 5], [1, 2], [2, 3], [3, 4]]; const Weight = [1, 1, 1, 1, 2, 2, 2]; console.log(maximumProduct(N, Edges, Weight)); |
C#
// C# code to implement the approach using System; using System.Collections.Generic; using System.Linq; class MainClass { // Stores the first and second largest // element in a connected component static int Max, sMax; // Stores the count of nodes // in the connected components static int cnt = 0; // Function to perform DFS Traversal // on a given graph and find the first // and the second largest elements static void dfs( int u, int N, List< bool > vis, List<List< int > > adj) { // Update the maximum value if (u > Max) { sMax = Max; Max = u; } // Update the second max value else if (u > sMax) { sMax = u; } // Increment size of component cnt++; // Mark current node visited vis[u] = true ; // Traverse the adjacent nodes for ( int i = 0; i < adj[u].Count; i++) { int to = adj[u][i]; // If to is not already visited if (!vis[to]) { dfs(to, N, vis, adj); } } return ; } // Function to find the maximum // product of a connected component static int MaximumProduct( int N, List<Tuple< int , int > > Edge, List< int > wt) { // Stores the count of edges int M = wt.Count; // Stores all the edges mapped // with a particular weight Dictionary< int , List<Tuple< int , int > > > mp = new Dictionary< int , List<Tuple< int , int > > >(); // Update the map mp for ( int i = 0; i < M; i++) { if (!mp.ContainsKey(wt[i])) { mp.Add(wt[i], new List<Tuple< int , int > >()); } mp[wt[i]].Add(Edge[i]); } var keys = mp.Keys.ToList(); keys.Sort(); keys.Reverse(); // Stores the result int res = 0; // Traverse the map mp foreach ( var i in keys) { // Stores the adjacency list List<List< int > > adj = new List<List< int > >(); for ( int j = 0; j <= N; j++) adj.Add( new List< int >()); // Stores the edges of // a particular weight List<Tuple< int , int > > v = mp[i]; // Traverse the vector v for ( int j = 0; j < v.Count; j++) { int U = v[j].Item1; int V = v[j].Item2; // Add an edge adj[U].Add(V); adj[V].Add(U); } // Stores if a vertex // is visited or not List< bool > vis = new List< bool >(); for ( int j = 0; j <= N; j++) vis.Add( false ); // Stores the maximum // size of a component int cntMax = 0; // Iterate over the range [1, N] for ( int u = 1; u <= N; u++) { // Assign Max, sMax, count = 0 Max = 0; sMax = 0; cnt = 0; // If vertex u is not visited if (!vis[u]) { dfs(u, N, vis, adj); // If cnt is greater // than cntMax if (cnt > cntMax) { // Update the res res = Max * sMax; cntMax = cnt; } // If already largest // connected component else if (cnt == cntMax) { // Update res res = Math.Max(res, Max * sMax); } } } } // Return res return res; } // Driver Code public static void Main( string [] args) { int N = 5; List<Tuple< int , int > > Edges = new List<Tuple< int , int > >(); Edges.Add(Tuple.Create(1, 2)); Edges.Add(Tuple.Create(2, 5)); Edges.Add(Tuple.Create(3, 5)); Edges.Add(Tuple.Create(4, 5)); Edges.Add(Tuple.Create(1, 2)); Edges.Add(Tuple.Create(2, 3)); Edges.Add(Tuple.Create(3, 4)); List< int > Weight = new List< int >{ 1, 1, 1, 1, 2, 2, 2 }; Console.WriteLine(MaximumProduct(N, Edges, Weight)); } } // This code is contributed by phasing17 |
20
Time Complexity: O(N2 * log N + M)
Auxiliary Space: O(N2)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!