给定一个由N个顶点和M 个边组成的无向图,以及类型为{X, Y} 的查询Q[][] ,任务是检查顶点X和Y是否在图的同一个连通分量中。
例子:
Input: Q[][] = {{1, 5}, {3, 2}, {5, 2}}
Graph:
Output: Yes No No
Explanation:
From the given graph, it can be observed that the vertices {1, 5} are in the same connected component.
But {3, 2} and {5, 2} are from different components.
Input: Q[][] = {{1, 9}, {2, 8}, {3, 5}, {7, 9}}
Graph:
Output: No Yes No Yes
Explanation:
From the given graph, it can be observed that the vertices {2, 8} and {7, 9} is from same connected component.
But {1, 9} and {3, 5} are from different components.
方法:思路是使用 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 现场工作专业课程和学生竞争性编程现场课程。