📜  使用 Graph 计算不同组的数量

📅  最后修改于: 2021-10-25 05:03:14             🧑  作者: Mango

给定一个包含N 个节点的图,其值为PM 。还给定K对整数作为(x, y)表示图中的边,这样如果a连接到b并且b连接到c那么ac也将连接。

单个连接的组件称为组。该组可以同时具有PM值。如果P值大于M值,则该组称为P影响,对于M也类似。如果PM 的数量相等,则称为中性群。任务是找出P受影响、 M受影响和中立群体的数量。

例子:

方法:用邻接表构造一个图,从1到N循环,做DFS,检查P和M的计数比较容易。
另一种方法是使用 DSU 稍加修改,大小数组将是成对的,以便它可以保持M 和 P的计数。在这种方法中,不需要构建图,因为合并操作将处理连接的组件。请注意,您应该按大小/等级了解 DSU 以进行优化。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// To store the parents
// of the current node
vector par;
 
// To store the size of M and P
vector > sz;
 
// Function for initialization
void init(vector& nodes)
{
 
    // Size of the graph
    int n = (int)nodes.size();
 
    par.clear();
    sz.clear();
    par.resize(n + 1);
    sz.resize(n + 1);
 
    for (int i = 0; i <= n; ++i) {
        par[i] = i;
 
        if (i > 0) {
 
            // If the node is P
            if (nodes[i - 1] == 'P')
                sz[i] = { 0, 1 };
 
            // If the node is M
            else
                sz[i] = { 1, 0 };
        }
    }
}
 
// To find the parent of
// the current node
int parent(int i)
{
    while (par[i] != i)
        i = par[i];
    return i;
}
 
// Merge funtion
void unin(int a, int b)
{
    a = parent(a);
    b = parent(b);
 
    if (a == b)
        return;
 
    // Total size by adding number of M and P
    int sz_a = sz[a].first + sz[a].second;
    int sz_b = sz[b].first + sz[b].second;
 
    if (sz_a < sz_b)
        swap(a, b);
 
    par[b] = a;
    sz[a].first += sz[b].first;
    sz[a].second += sz[b].second;
    return;
}
 
// Function to calculate the influenced value
void influenced(vector& nodes,
                vector > connect)
{
 
    // Number of nodes
    int n = (int)nodes.size();
 
    // Initialization function
    init(nodes);
 
    // Size of the connected vector
    int k = connect.size();
 
    // Performing union operation
    for (int i = 0; i < k; ++i) {
        unin(connect[i].first, connect[i].second);
    }
 
    // ne = Number of neutal groups
    // ma = Number of M influenced groups
    // pe = Number of P influenced groups
    int ne = 0, ma = 0, pe = 0;
 
    for (int i = 1; i <= n; ++i) {
        int x = parent(i);
 
        if (x == i) {
            if (sz[i].first == sz[i].second) {
                ne++;
            }
            else if (sz[i].first > sz[i].second) {
                ma++;
            }
            else {
                pe++;
            }
        }
    }
 
    cout << "P = " << pe << "\nM = "
         << ma << "\nN = " << ne << "\n";
}
 
// Driver code
int main()
{
 
    // Nodes at each index ( 1 - base indexing )
    vector nodes = { 'P', 'M', 'P', 'M', 'P' };
 
    // Connected Pairs
    vector > connect = {
        { 1, 3 },
        { 3, 5 },
        { 4, 5 }
    };
 
    influenced(nodes, connect);
 
    return 0;
}


Java
// Java implementation of the approach
import java.io.*;
import java.util.*;
 
class GFG{
     
// To store the parents
// of the current node
static ArrayList par = new ArrayList();
 
// To store the size of M and P
static ArrayList<
       ArrayList> sz = new ArrayList<
                                    ArrayList>();
                                     
// Function for initialization
static void init(ArrayList nodes)
{
     
    // Size of the graph
    int n = nodes.size();
    for(int i = 0; i <= n; ++i)
    {
        par.add(i);
         
        if (i == 0)
        {
            sz.add(new ArrayList(
                Arrays.asList(0, 0)));
        }
         
        if (i > 0)
        {
             
            // If the node is P
            if (nodes.get(i - 1) == 'P')
            {
                sz.add(new ArrayList(
                    Arrays.asList(0, 1)));
            }
             
            // If the node is M
            else
            {
                sz.add(new ArrayList(
                    Arrays.asList(1, 0)));
            }
        }
    }
}
 
// To find the parent of
// the current node
static int parent(int i)
{
    while (par.get(i) != i)
    {
        i = par.get(i);
    }
    return i;
}
 
// Merge funtion
static void unin(int a, int b)
{
    a = parent(a);
    b = parent(b);
     
    if (a == b)
    {
        return;
    }
     
    // Total size by adding number
    // of M and P
    int sz_a = sz.get(a).get(0) +
               sz.get(a).get(1);
    int sz_b = sz.get(b).get(0) +
               sz.get(b).get(1);
                
    if (sz_a < sz_b)
    {
        int temp = a;
        a = b;
        b = temp;
    }
    par.set(b, a);
     
    sz.get(a).set(0, sz.get(a).get(0) +
                     sz.get(b).get(0));
    sz.get(a).set(1, sz.get(a).get(1) +
                     sz.get(b).get(1));
    return;
}
 
// Function to calculate the influenced value
static void influenced(ArrayList nodes,
             ArrayList> connect)
{
     
    // Number of nodes
    int n = nodes.size();
     
    // Initialization function
    init(nodes);
     
    // Size of the connected vector
    int k = connect.size();
     
    // Performing union operation
    for(int i = 0; i < k; ++i)
    {
        unin(connect.get(i).get(0),
             connect.get(i).get(1));
    }
     
    // ne = Number of neutal groups
    // ma = Number of M influenced groups
    // pe = Number of P influenced groups
    int ne = 0, ma = 0, pe = 0;
    for(int i = 1; i <= n; ++i)
    {
        int x = parent(i);
         
        if (x == i)
        {
            if (sz.get(i).get(0) ==
                sz.get(i).get(1))
            {
                ne++;
            }
            else if (sz.get(i).get(0) >
                     sz.get(i).get(1))
            {
                ma++;
            }
            else
            {
                pe++;
            }
        }
    }
    System.out.println("P = " + pe +
                     "\nM = " + ma +
                     "\nN = " + ne);
}
 
// Driver code
public static void main(String[] args)
{
     
    // Nodes at each index ( 1 - base indexing )
    ArrayList nodes = new ArrayList();
    nodes.add('P');
    nodes.add('M');
    nodes.add('P');
    nodes.add('M');
    nodes.add('P');
     
    // Connected Pairs
    ArrayList<
    ArrayList> connect = new ArrayList<
                                      ArrayList>();
    connect.add(new ArrayList(
        Arrays.asList(1, 3)));
    connect.add(new ArrayList(
        Arrays.asList(3, 5)));
    connect.add(new ArrayList(
        Arrays.asList(4, 5)));
         
    influenced(nodes, connect);
}
}
 
// This code is contributed by avanitrachhadiya2155


Python3
# Python3 implementation of the approach
 
# To store the parents
# of the current node
par = []
 
# To store the size of M and P
sz = []
 
# Function for initialization
def init(nodes):
 
    # Size of the graph
    n = len(nodes)
    for i in range(n + 1):
        par.append(0)
        sz.append(0)
 
    for i in range(n + 1):
        par[i] = i
 
        if (i > 0):
 
            # If the node is P
            if (nodes[i - 1] == 'P'):
                sz[i] = [0, 1]
 
            # If the node is M
            else:
                sz[i] = [1, 0]
 
# To find the parent of
# the current node
def parent(i):
    while (par[i] != i):
        i = par[i]
    return i
 
# Merge funtion
def unin(a, b):
    a = parent(a)
    b = parent(b)
 
    if (a == b):
        return
 
    # Total size by adding number of M and P
    sz_a = sz[a][0] + sz[a][1]
    sz_b = sz[b][0] + sz[b][1]
 
    if (sz_a < sz_b):
        a, b = b, a
 
    par[b] = a
    sz[a][0] += sz[b][0]
    sz[a][1] += sz[b][1]
    return
 
# Function to calculate the influenced value
def influenced(nodes,connect):
 
    # Number of nodes
    n = len(nodes)
 
    # Initialization function
    init(nodes)
 
    # Size of the connected vector
    k = len(connect)
 
    # Performing union operation
    for i in range(k):
        unin(connect[i][0], connect[i][1])
 
    # ne = Number of neutal groups
    # ma = Number of M influenced groups
    # pe = Number of P influenced groups
    ne = 0
    ma = 0
    pe = 0
 
    for i in range(1, n + 1):
        x = parent(i)
 
        if (x == i):
            if (sz[i][0] == sz[i][1]):
                ne += 1
            elif (sz[i][0] > sz[i][1]):
                ma += 1
            else:
                pe += 1
 
    print("P =",pe,"\nM =",ma,"\nN =",ne)
 
# Driver code
 
# Nodes at each index ( 1 - base indexing )
nodes = [ 'P', 'M', 'P', 'M', 'P' ]
 
# Connected Pairs
connect = [ [ 1, 3 ],
            [ 3, 5 ],
            [ 4, 5 ] ]
 
influenced(nodes, connect)
 
# This code is contributed by mohit kumar 29


C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
 
class GFG{
     
// To store the parents
// of the current node
static List par = new List();
 
// To store the size of M and P
static List> sz = new List>();
 
// Function for initialization
static void init(List nodes)
{
     
    // Size of the graph
    int n = nodes.Count;
    for(int i = 0; i <= n; ++i)
    {
        par.Add(i);
         
        if (i == 0)
        {
            sz.Add(new List(){0, 0});
        }
         
        if (i > 0)
        {
             
            // If the node is P
            if (nodes[i - 1] == 'P')
            {
                sz.Add(new List(){0, 1});
                 
            }
             
            // If the node is M
            else
            {
                sz.Add(new List(){1, 0});
            }
        }
    }
}
 
// To find the parent of
// the current node
static int parent(int i)
{
    while (par[i] != i)
    {
        i = par[i];
    }
    return i;
}
 
// Merge funtion
static void unin(int a, int b)
{
    a = parent(a);
    b = parent(b);
     
    if (a == b)
    {
        return;
    }
     
    // Total size by adding number
    // of M and P
    int sz_a = sz[a][0] + sz[a][1];
    int sz_b = sz[b][0] + sz[b][1];
     
    if (sz_a < sz_b)
    {
        int temp = a;
        a = b;
        b = temp;
    }
     
    par[b] = a;
    sz[a][0] += sz[b][0];
    sz[a][1] += sz[b][1];
    return;
}
 
// Function to calculate the influenced value
static void influenced(List nodes,
                       List> connect)
{
     
    // Number of nodes
    int n = nodes.Count;
     
    // Initialization function
    init(nodes);
     
    // Size of the connected vector
    int k = connect.Count;
     
    // Performing union operation
    for(int i = 0; i < k; ++i)
    {
        unin(connect[i][0], connect[i][1]);
    }
     
    // ne = Number of neutal groups
    // ma = Number of M influenced groups
    // pe = Number of P influenced groups
    int ne = 0, ma = 0, pe = 0;
    for(int i = 1; i <= n; ++i)
    {
        int x = parent(i);
         
        if (x == i)
        {
            if (sz[i][0] == sz[i][1])
            {
                ne++;
            }
            else if (sz[i][0] > sz[i][1])
            {
                ma++;
            }
            else
            {
                pe++;
            }
        }
    }
    Console.WriteLine("P = " + pe + "\nM = " +
                      ma + "\nN = " + ne);
}
 
// Driver code
static public void Main()
{
     
    // Nodes at each index ( 1 - base indexing )
    List nodes = new List(){'P', 'M', 'P', 'M', 'P'};
     
    // Connected Pairs
    List> connect = new List>();
    connect.Add(new List(){1, 3});
    connect.Add(new List(){3, 5});
    connect.Add(new List(){4, 5});
     
    influenced(nodes, connect);
}
}
 
// This code is contributed by rag2127


Javascript


输出:
P = 1
M = 1
N = 0

时间复杂度: O(N)。
辅助空间:O(N)。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程