Count of different groups using Graph

Given a graph with N nodes having values either P or M. Also given K pairs of integers as (x, y) representing the edges in the graph such that if a is connected to b and b is connected to c then a and c will also be connected.
A single connected component is called a group. The group can have both P and M values. If the P values are more than the M values this group is called P influenced and similarly for M. If the number of P’s and M’s are equal then it is called a neutral group. The task is to find the number of P influenced, M influenced and, Neutral groups.

Examples:

Input: Nodes[] = {P, M, P, M, P}, edges[][] = {
{1, 3},
{4, 5},
{3, 5}}
Output:
P = 1
M = 1
N = 0
There will be two groups of indexes
{1, 3, 4, 5} and {2}.
The first group is P influenced and
the second one is M influenced.



Input: Nodes[] = {P, M, P, M, P}, edges[][] = {
{1, 3},
{4, 5}}
Output:
P = 1
M = 2
N = 0

Approach: It is easier to construct a graph with adjacency list and loop from 1 to N and do DFS and check the count of P and M.
Another way is to use DSU with a little modification that size array will be of pair so that it can maintain the count of both M and P. In this approach, there is no need to construct the graph as the merge operation will take care of the connected component. Note that you should have the knowledge of DSU by size/rank for optimization.

Below is the implementation of the above approach:

CPP

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// To store the parents
// of the current node
vector<int> par;
  
// To store the size of M and P
vector<pair<int, int> > sz;
  
// Function for intialization
void init(vector<char>& 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<char>& nodes,
                vector<pair<int, int> > connect)
{
  
    // Number of nodes
    int n = (int)nodes.size();
  
    // Intialization 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<char> nodes = { 'P', 'M', 'P', 'M', 'P' };
  
    // Connected Pairs
    vector<pair<int, int> > connect = {
        { 1, 3 },
        { 3, 5 },
        { 4, 5 }
    };
  
    influenced(nodes, connect);
  
    return 0;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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 intialization
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)
  
    # Intialization 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

chevron_right


Output:

P = 1
M = 1
N = 0



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : mohit kumar 29