📜  图的连通分量数(使用 Disjoint Set Union )

📅  最后修改于: 2021-10-27 08:12:37             🧑  作者: Mango

给定一个顶点编号在[0, N]范围内的无向图G和一个由M 个边组成的数组Edges[][] ,任务是使用 Disjoint Set Union 算法找到图中连通分量的总数。

例子:

方法:该问题可以使用 Disjoint Set Union 算法解决。请按照以下步骤解决问题:

  • 在DSU算法中,主要有两个函数,即connect()root()函数。
  • connect():连接一条边。
  • root():递归确定给定边的最顶层父级。
  • 对于每条边{a, b},检查a是否连接到b 。如果发现是错误的,通过附加他们的顶级父母来连接他们。
  • 在对每条边完成上述步骤后,打印每个顶点的不同的最顶层父项的总数。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Stores the parent of each vertex
int parent[1000000];
 
// Function to find the topmost
// parent of vertex a
int root(int a)
{
    // If current vertex is
    // the topmost vertex
    if (a == parent[a]) {
        return a;
    }
 
    // Otherwsie, set topmost vertex of
    // its parent as its topmost vertex
    return parent[a] = root(parent[a]);
}
 
// Function to connect the component
// having vertex a with the component
// having vertex b
void connect(int a, int b)
{
    // Connect edges
    a = root(a);
    b = root(b);
 
    if (a != b) {
        parent[b] = a;
    }
}
 
// Function to find unique top most parents
void connectedComponents(int n)
{
    set s;
 
    // Traverse all vertices
    for (int i = 0; i < n; i++) {
 
        // Insert all topmost
        // vertices obtained
        s.insert(root(parent[i]));
    }
 
    // Print count of connected components
    cout << s.size() << '\n';
}
 
// Function to print answer
void printAnswer(int N,
                 vector > edges)
{
 
    // Setting parent to itself
    for (int i = 0; i <= N; i++) {
        parent[i] = i;
    }
 
    // Traverse all edges
    for (int i = 0; i < edges.size(); i++) {
        connect(edges[i][0], edges[i][1]);
    }
 
    // Print answer
    connectedComponents(N);
}
 
// Driver Code
int main()
{
    // Given N
    int N = 8;
 
    // Given edges
    vector > edges = {
        { 1, 0 }, { 0, 2 }, { 5, 3 }, { 3, 4 }, { 6, 7 }
    };
 
    // Function call
    printAnswer(N, edges);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
class GFG{
 
// Stores the parent of each vertex
static int []parent = new int[1000000];
 
// Function to find the topmost
// parent of vertex a
static int root(int a)
{
   
    // If current vertex is
    // the topmost vertex
    if (a == parent[a])
    {
        return a;
    }
 
    // Otherwsie, set topmost vertex of
    // its parent as its topmost vertex
    return parent[a] = root(parent[a]);
}
 
// Function to connect the component
// having vertex a with the component
// having vertex b
static void connect(int a, int b)
{
   
    // Connect edges
    a = root(a);
    b = root(b);
 
    if (a != b) {
        parent[b] = a;
    }
}
 
// Function to find unique top most parents
static void connectedComponents(int n)
{
    HashSet s = new HashSet();
 
    // Traverse all vertices
    for (int i = 0; i < n; i++)
    {
 
        // Insert all topmost
        // vertices obtained
        s.add(parent[i]);
    }
 
    // Print count of connected components
    System.out.println(s.size());
}
 
// Function to print answer
static void printAnswer(int N,int [][] edges)
{
 
    // Setting parent to itself
    for (int i = 0; i <= N; i++)
    {
        parent[i] = i;
    }
 
    // Traverse all edges
    for (int i = 0; i < edges.length; i++)
    {
        connect(edges[i][0], edges[i][1]);
    }
 
    // Print answer
    connectedComponents(N);
}
 
// Driver Code
public static void main(String[] args)
{
   
    // Given N
    int N = 8;
 
    // Given edges
   int [][]edges = {{ 1, 0 }, { 0, 2 },
                    { 5, 3 }, { 3, 4 },
                    { 6, 7 }};
 
    // Function call
    printAnswer(N, edges);
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 program for the above approach
 
# Stores the parent of each vertex
parent = [0]*(1000000)
  
# Function to find the topmost
# parent of vertex a
def root(a) :
    
    # If current vertex is
    # the topmost vertex
    if (a == parent[a]) :       
        return a
         
    # Otherwsie, set topmost vertex of
    # its parent as its topmost vertex
    parent[a] = root(parent[a])
    return parent[a]
     
# Function to connect the component
# having vertex a with the component
# having vertex b
def connect(a, b) :
    
    # Connect edges
    a = root(a)
    b = root(b)
  
    if (a != b) :
        parent[b] = a
         
# Function to find unique top most parents
def connectedComponents(n) :
 
    s = set()
  
    # Traverse all vertices
    for i in range(n) :
  
        # Insert all topmost
        # vertices obtained
        s.add(root(parent[i]))
  
    # Print count of connected components
    print(len(s))
     
# Function to print answer
def printAnswer(N, edges) :
  
    # Setting parent to itself
    for i in range(N + 1) :  
        parent[i] = i
  
    # Traverse all edges
    for i in range(len(edges)) :   
        connect(edges[i][0], edges[i][1])
  
    # Print answer
    connectedComponents(N)
     
# Given N
N = 6
 
# Given edges
edges = [[ 1, 0 ], [ 2, 3 ], [ 1, 2 ], [ 4, 5 ]]
 
# Function call
printAnswer(N, edges)
 
# This code is contributed by divyesh072019


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
     
    // Stores the parent of each vertex
    static int[] parent = new int[1000000];
       
    // Function to find the topmost
    // parent of vertex a
    static int root(int a)
    {
        // If current vertex is
        // the topmost vertex
        if (a == parent[a]) {
            return a;
        }
       
        // Otherwsie, set topmost vertex of
        // its parent as its topmost vertex
        return parent[a] = root(parent[a]);
    }
       
    // Function to connect the component
    // having vertex a with the component
    // having vertex b
    static void connect(int a, int b)
    {
        // Connect edges
        a = root(a);
        b = root(b);
       
        if (a != b) {
            parent[b] = a;
        }
    }
       
    // Function to find unique top most parents
    static void connectedComponents(int n)
    {
        HashSet s = new HashSet();
       
        // Traverse all vertices
        for (int i = 0; i < n; i++) {
       
            // Insert all topmost
            // vertices obtained
            s.Add(parent[i]);
        }
       
        // Print count of connected components
        Console.WriteLine(s.Count);
    }
       
    // Function to print answer
    static void printAnswer(int N, List > edges)
    {
       
        // Setting parent to itself
        for (int i = 0; i <= N; i++) {
            parent[i] = i;
        }
       
        // Traverse all edges
        for (int i = 0; i < edges.Count; i++) {
            connect(edges[i][0], edges[i][1]);
        }
       
        // Print answer
        connectedComponents(N);
    }  
 
  // Driver code
  static void Main() {
       
    // Given N
    int N = 8;
   
    // Given edges
    List> edges = new List>();
    edges.Add(new List { 1, 0 });
    edges.Add(new List { 0, 2 });
    edges.Add(new List { 5, 3 });
    edges.Add(new List { 3, 4 });
    edges.Add(new List { 6, 7 });
   
    // Function call
    printAnswer(N, edges);
  }
}
 
// This code is contributed by divyeshrabadiya07


Javascript


输出:
3

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

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