📌  相关文章
📜  检查顶点 X 和 Y 是否在无向图的同一个连通分量中的查询

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

给定一个由N个顶点和M 个边组成的无向图,以及类型为{X, Y} 的查询Q[][] ,任务是检查顶点XY是否在图的同一个连通分量中。

例子:

方法:思路是使用 Disjoint Set-Union 来解决问题。使用的 Disjoint set union 数据结构的基本接口如下:

  • make_set(v):创建一个由新元素 v 组成的新集合。
  • find_set(v):返回包含元素 v 的集合的代表。这是使用路径压缩优化的。
  • union_set(a, b):合并两个指定的集合(元素所在的集合,元素b所在的集合)。两个连接的顶点合并形成一个集合(Connected Components)。
  • 最初,所有顶点将是一个不同的集合(即它自己的父节点)并使用make_set函数形成。
  • 如果其中两个使用union_set函数连接,则将合并顶点。
  • 现在,对于每个查询,使用find_set函数检查给定的两个顶点是否来自同一集合。

下面是上述方法的实现:

C++
1-3-4   2
  |
  5   


Java
1-3-4  2-5-6  7-9
       |
       8   


Python3
// C++ Program to implement
// the above approach
#include 
using namespace std;
 
// Maximum number of nodes or
// vertices that can be present
// in the graph
#define MAX_NODES 100005
 
// Store the parent of each vertex
int parent[MAX_NODES];
 
// Stores the size of each set
int size_set[MAX_NODES];
 
// Function to initialize the
// parent of each vertices
void make_set(int v)
{
    parent[v] = v;
    size_set[v] = 1;
}
 
// Function to find the representative
// of the set which contain element v
int find_set(int v)
{
    if (v == parent[v])
        return v;
 
    // Path compression technique to
    // optimize the time complexity
    return parent[v]
           = find_set(parent[v]);
}
 
// Function to merge two different set
// into a single set by finding the
// representative of each set and merge
// the smallest set with the larger one
void union_set(int a, int b)
{
 
    // Finding the set representative
    // of each element
    a = find_set(a);
    b = find_set(b);
 
    // Check if they have different set
    // repersentative
    if (a != b) {
 
        // Compare the set sizes
        if (size_set[a] < size_set[b])
            swap(a, b);
 
        // Assign parent of smaller set
        // to the larger one
        parent[b] = a;
 
        // Add the size of smaller set
        // to the larger one
        size_set[a] += size_set[b];
    }
}
 
// Function to check the vertices
// are on the same set or not
string check(int a, int b)
{
    a = find_set(a);
    b = find_set(b);
 
    // Check if they have same
    // set representative or not
    return (a == b) ? "Yes" : "No";
}
 
// Driver Code
int main()
{
    int n = 5, m = 3;
 
    make_set(1);
    make_set(2);
    make_set(3);
    make_set(4);
    make_set(5);
 
    // Connected vertices and taking
    // them into single set
    union_set(1, 3);
    union_set(3, 4);
    union_set(3, 5);
 
    // Number of queries
    int q = 3;
 
    // Function call
    cout << check(1, 5) << endl;
    cout << check(3, 2) << endl;
    cout << check(5, 2) << endl;
 
    return 0;
}


C#
// Java Program to implement
// the above approach
import java.util.*;
class GFG{
 
// Maximum number of nodes or
// vertices that can be present
// in the graph
static final int MAX_NODES = 100005;
 
// Store the parent of each vertex
static int []parent = new int[MAX_NODES];
 
// Stores the size of each set
static int []size_set = new int[MAX_NODES];
 
// Function to initialize the
// parent of each vertices
static void make_set(int v)
{
    parent[v] = v;
    size_set[v] = 1;
}
 
// Function to find the representative
// of the set which contain element v
static int find_set(int v)
{
    if (v == parent[v])
        return v;
 
    // Path compression technique to
    // optimize the time complexity
    return parent[v] = find_set(parent[v]);
}
 
// Function to merge two different set
// into a single set by finding the
// representative of each set and merge
// the smallest set with the larger one
static void union_set(int a, int b)
{
 
    // Finding the set representative
    // of each element
    a = find_set(a);
    b = find_set(b);
 
    // Check if they have different set
    // repersentative
    if (a != b) {
 
        // Compare the set sizes
        if (size_set[a] < size_set[b])
        {
            a = a+b;
            b = a-b;
            a = a-b;
        }
 
        // Assign parent of smaller set
        // to the larger one
        parent[b] = a;
 
        // Add the size of smaller set
        // to the larger one
        size_set[a] += size_set[b];
    }
}
 
// Function to check the vertices
// are on the same set or not
static String check(int a, int b)
{
    a = find_set(a);
    b = find_set(b);
 
    // Check if they have same
    // set representative or not
    return (a == b) ? "Yes" : "No";
}
 
// Driver Code
public static void main(String[] args)
{
    int n = 5, m = 3;
 
    make_set(1);
    make_set(2);
    make_set(3);
    make_set(4);
    make_set(5);
 
    // Connected vertices and taking
    // them into single set
    union_set(1, 3);
    union_set(3, 4);
    union_set(3, 5);
 
    // Number of queries
    int q = 3;
 
    // Function call
    System.out.print(check(1, 5) + "\n");
    System.out.print(check(3, 2) + "\n");
    System.out.print(check(5, 2) + "\n");
}
}
 
// This code is contributed by Rohit_ranjan


Javascript
# Python3 Program to implement
# the above approach
 
# Maximum number of nodes or
# vertices that can be present
# in the graph
MAX_NODES = 100005
  
# Store the parent of each vertex
parent = [0 for i in range(MAX_NODES)];
  
# Stores the size of each set
size_set = [0 for i in range(MAX_NODES)];
  
# Function to initialize the
# parent of each vertices
def make_set(v):
     
    parent[v] = v;
    size_set[v] = 1;
  
# Function to find the
# representative of the
# set which contain element v
def find_set(v):
 
    if (v == parent[v]):
        return v;
  
    # Path compression technique to
    # optimize the time complexity
    parent[v] = find_set(parent[v]);
     
    return parent[v]
  
# Function to merge two
# different set into a
# single set by finding the
# representative of each set
# and merge the smallest set
# with the larger one
def union_set(a, b):
  
    # Finding the set
    # representative
    # of each element
    a = find_set(a);
    b = find_set(b);
  
    # Check if they have
    # different set
    # repersentative
    if (a != b):
  
        # Compare the set sizes
        if (size_set[a] <
            size_set[b]):
            swap(a, b);
  
        # Assign parent of
        # smaller set to
        # the larger one
        parent[b] = a;
  
        # Add the size of smaller set
        # to the larger one
        size_set[a] += size_set[b];
  
# Function to check the vertices
# are on the same set or not
def check(a, b):
 
    a = find_set(a);
    b = find_set(b);
  
    # Check if they have same
    # set representative or not
    if a == b:
        return ("Yes")
    else:
        return ("No")
 
# Driver code     
if __name__=="__main__":
     
    n = 5
    m = 3;
  
    make_set(1);
    make_set(2);
    make_set(3);
    make_set(4);
    make_set(5);
  
    # Connected vertices
    # and taking them
    # into single set
    union_set(1, 3);
    union_set(3, 4);
    union_set(3, 5);
  
    # Number of queries
    q = 3;
  
    # Function call
    print(check(1, 5))
    print(check(3, 2))
    print(check(5, 2))
 
# This code is contributed by rutvik_56


输出:
// C# program to implement
// the above approach
using System;
 
class GFG{
 
// Maximum number of nodes or
// vertices that can be present
// in the graph
static readonly int MAX_NODES = 100005;
 
// Store the parent of each vertex
static int []parent = new int[MAX_NODES];
 
// Stores the size of each set
static int []size_set = new int[MAX_NODES];
 
// Function to initialize the
// parent of each vertices
static void make_set(int v)
{
    parent[v] = v;
    size_set[v] = 1;
}
 
// Function to find the representative
// of the set which contain element v
static int find_set(int v)
{
    if (v == parent[v])
        return v;
 
    // Path compression technique to
    // optimize the time complexity
    return parent[v] = find_set(parent[v]);
}
 
// Function to merge two different set
// into a single set by finding the
// representative of each set and merge
// the smallest set with the larger one
static void union_set(int a, int b)
{
 
    // Finding the set representative
    // of each element
    a = find_set(a);
    b = find_set(b);
 
    // Check if they have different set
    // repersentative
    if (a != b)
    {
         
        // Compare the set sizes
        if (size_set[a] < size_set[b])
        {
            a = a + b;
            b = a - b;
            a = a - b;
        }
 
        // Assign parent of smaller set
        // to the larger one
        parent[b] = a;
 
        // Add the size of smaller set
        // to the larger one
        size_set[a] += size_set[b];
    }
}
 
// Function to check the vertices
// are on the same set or not
static String check(int a, int b)
{
    a = find_set(a);
    b = find_set(b);
 
    // Check if they have same
    // set representative or not
    return (a == b) ? "Yes" : "No";
}
 
// Driver Code
public static void Main(String[] args)
{
    //int n = 5, m = 3;
 
    make_set(1);
    make_set(2);
    make_set(3);
    make_set(4);
    make_set(5);
 
    // Connected vertices and taking
    // them into single set
    union_set(1, 3);
    union_set(3, 4);
    union_set(3, 5);
 
    // Number of queries
    //int q = 3;
 
    // Function call
    Console.Write(check(1, 5) + "\n");
    Console.Write(check(3, 2) + "\n");
    Console.Write(check(5, 2) + "\n");
}
}
 
// This code is contributed by Amit Katiyar

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

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