本文先是给出三篇并查集原理解释文章链接,又提供了python代码模版;而后给出了一份蓝桥杯并查集的题单,并附有部分题目及其求解思路、代码。
目录部分
并查集原理
python代码
并查集题单
蓝桥幼儿园
题目描述
输入描述
输出描述
输入输出样例
求解
并查集原理
并查集(Disjoint Set),顾名思义,用于处理不相交集合的合并问题。
【算法与数据结构】—— 并查集_theSerein的博客-CSDN博客
并查集(高级数据结构)-蓝桥杯_蓝桥杯并查集_ranzi.的博客-CSDN博客
推荐看:并查集教程_陈子昂-北工大的博客-CSDN博客
python代码
def init_set(N):
s=list(range(N))
def merge_set(x,y):
x=find_set(x)
y=find_set(y)
if x!=y:s[x]=s[y]
def find_set(x):
if s[x]!=x:s[x]=find_set(s[x])
else:return s[x]
并查集题单
蓝桥oj:
1135:蓝桥幼儿园
110:合根植物
185:修改数组
595:七段码
1085:小猪存钱罐
1084:火星旅行
1012:方格染色
828:星球大战
2094:推导部分和
蓝桥幼儿园
题目描述
蓝桥幼儿园的学生是如此的天真无邪,以至于对他们来说,朋友的朋友就是自己的朋友。
小明是蓝桥幼儿园的老师,这天他决定为学生们举办一个交友活动,活动规则如下:
小明会用红绳连接两名学生,被连中的两个学生将成为朋友。
小明想让所有学生都互相成为朋友,但是蓝桥幼儿园的学生实在太多了,他无法用肉眼判断某两个学生是否为朋友。于是他起来了作为编程大师的你,请你帮忙写程序判断某两个学生是否为朋友(默认自己和自己也是朋友)。
输入描述
第 11 行包含两个正整数N,M,其中 N 表示蓝桥幼儿园的学生数量,学生的编号分别为1∼N。
之后的第2∼M+1 行每行输入三个整数,op,x,y:
- 如果 op=1,表示小明用红绳连接了学生 x 和学生 y 。
- 如果 op=2,请你回答小明学生 x 和 学生 y 是否为朋友。
1≤N,M≤2×10^5,1≤x,y≤N。
输出描述
对于每个 op=2 的输入,如果 x 和 y 是朋友,则输出一行 YES
,否则输出一行 NO
。
输入输出样例
示例 1
输入
5 5
2 1 2
1 1 3
2 1 3
1 2 3
2 1 2
输出
NO
YES
YES
求解
模板题。注意样例,输入两次212的输出不一样,表明程序是接受到op2的输入后立即判断,而不是等所有输入完后再判断两个学生是否为朋友的。
import sys
sys.setrecursionlimit(int(1e9))
def merge_s(x,y):
x=find_s(x)
y=find_s(y)
if x!=y:s[x]=s[y]
def find_s(x):
if s[x]!=x:s[x]=find_s(s[x])
return s[x]
n,m=map(int,input().split())
s=list(range(n+10))
for _ in range(m):
op,x,y=map(int,input().split())
if op==1:
merge_s(x,y)
else:
if find_s(x)==find_s(y): print("YES")
else:print("NO")
合根植物
题目描述
w 星球的一个种植园,被分成m×n 个小格子(东西方向 m 行,南北方向 n 列)。每个格子里种了一株合根植物。
这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。
如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗?
输入描述
第一行,两个整数 m,n,用空格分开,表示格子的行数、列数1≤m,n≤1000)。
接下来一行,一个整数 k (0≤k≤10^5 ),表示下面还有 k 行数据。
接下来 k 行,每行两个整数a,b,表示编号为 a 的小格子和编号为 b 的小格子合根了。
格子的编号一行一行,从上到下,从左到右编号。
比如:5×4 的小格子,编号:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 19 20
输出描述
输出植物数量。
输入输出样例
示例
输入
5 4
16
2 3
1 5
5 9
4 8
7 8
9 10
10 11
11 12
10 14
12 16
14 18
17 18
15 19
19 20
9 13
13 17
输出
5
样例说明
其合根情况参考下图:
求解
修改merge_set函数。
def merge(x,y):
global pn
x=find(x)
y=find(y)
if x!=y:
s[x]=s[y]
pn-=1
def find(x):
if x!=s[x]:
s[x]=find(s[x])
return s[x]
m,n=map(int,input().split())
k=int(input())
pn=m*n
s=list(range(m*n+1))
for _ in range(k):
a,b=map(int,input().split())
merge(a,b)
print(pn)