📌  相关文章
📜  图中最大连接组件的一对节点的最大乘积

📅  最后修改于: 2021-04-29 14:56:28             🧑  作者: Mango

给定一个由N个顶点和M个边缘组成的无向加权图G ,以及由该图的M个边缘组成的两个数组Edges [] [2]Weight [] 重量 通过分别连接所有具有相同权重的边而形成的图,该任务的任务是分别找到图的最大连接部分的任意两个顶点的最大乘积。

例子:

方法:可以通过在给定图上执行DFS遍历并针对相同权重的所有已连接组件最大化第一和第二最大节点的乘积来解决给定问题。请按照以下步骤解决问题:

  • 将与所有唯一权重对应的所有边存储在地图M中
  • 初始化一个变量,例如res0,以存储相同权重的已连接组件的任何两个节点的最大乘积。
  • 遍历地图,并为每个键作为权重,通过连接映射有特定权重的所有边来创建图形,并执行以下操作:
    • 找到最大值(例如M1 )和第二个最大值(例如M2 )节点的值以及 通过在创建的图形上执行DFS遍历,可以图形的所有连接组件的大小。
    • 如果当前连接的组件的大小至少是先前找到的最大连接的组件的大小,则将res的值更新为resM1M2的最大值。
  • 完成上述步骤后,将res的值打印为最大乘积。

下面是上述方法的实现:

C++
// C++ program for the above approach
  
#include 
using namespace std;
  
// Stores the first and second largest
// element in a connected componenet
int Max, sMax;
  
// Stores the count of nodes
// in the connected componenets
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& vis,
         vector >& 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 > Edge,
    vector wt)
{
    // Stores the count of edges
    int M = wt.size();
  
    // Stores all the edges mapped
    // with a particular weight
    unordered_map > >
        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 > adj(N + 1);
  
        // Stores the edges of
        // a particular weight
        vector > 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 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 > Edges
        = { { 1, 2 }, { 2, 5 }, { 3, 5 }, { 4, 5 }, { 1, 2 }, { 2, 3 }, { 3, 4 } };
  
    vector Weight = { 1, 1, 1, 1,
                           2, 2, 2 };
    cout << MaximumProduct(N, Edges, Weight);
  
    return 0;
}


输出:
20

时间复杂度: O(N 2 * log N + M)
辅助空间: O(N 2 )