Open In App

Maximum product of a pair of nodes from largest connected component in a Graph

Improve
Improve
Like Article
Like
Save
Share
Report

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


Output: 

20

 

Time Complexity: O(N2 * log N + M)
Auxiliary Space: O(N2)



Last Updated : 30 Jan, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads