首页 > 编程语言 >并查集——蓝桥杯备赛【python】

并查集——蓝桥杯备赛【python】

时间:2024-04-07 15:33:44浏览次数:31  
标签:__ 函数 merge python 查集 find 蓝桥 fa 节点

一、合根植物

试题链接:[蓝桥杯 2017 国 C] 合根植物

问题描述

星球的一个种植园,被分成 m×n 个小格子(东西方向 m 行,南北方向 n 列)。每个格子里种了一株合根植物。这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗?

输入描述
第一行,两个整数 m,n,用空格分开,表示格子的行数、列数(1 < m,n < 1000)。

接下来一行,一个整数 k,表示下面还有k 行数据(0 < k< 10^5)。

接下来k行,每行两个整数 a,b,表示编号为 a的小格子和编号为b的小格子合根了。

格子的编号一行一行,从上到下,从左到右编号。比如:5x4的小格子,编号:

1234
5678
9101112
13141516
17181920

输出描述

一行一个整数,表示答案。

输入样例

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

样例解释

 


问题分析

首先由题目可知最多可能有10^6个数据,所以我们设置列表的时候要设置够数量。

对于任给的两个节点,要将其接在一起,就用merge函数来实现,即把第一个节点(树)挂在第二个节点(树)上。

find函数是用来找该节点的“祖宗”(根节点)的,fa列表表示第i个节点的父节点,我们在调用find函数时也不断地更新父节点,让其变为其根节点。

find函数和merge函数都要记下的。

最后我们来判断一下根节点有几个(根节点一直没动,其值i就等于fa[i])


代码示例

def merge(x,y):
    fa[find(x)]=find(y)
def find(x):
    if x==fa[x]:
        return x
    else:
        fa[x]=find(fa[x])
        return fa[x]

if __name__=="__main__":
    fa=[i for i in range(1000000)]
    m,n=map(int,input().split())
    k=int(input())
    for i in range(k):
        a,b=map(int,input().split())
        merge(a,b)
    x=m*n
    ans=0
    for i in range(1,x+1):
        if i ==fa[i]:
            ans+=1
    print(ans)

二、修改数组

试题链接:[蓝桥杯 2019 省 A] 修改数组

问题描述

输入示例

5

2 1 1 3 4

输出示例

2 1 3 4 5 


问题分析

对于该题,我们可以用树来做,好处是:比如在输入样例中,1已经出现了一次,那么我们自动会更新其fa[1]=3(即其根节点为3)那么我们在再次遇到1时即可直接得出3,而不用判断1是否在之前出现过,2(1+1)是否在之前出现过。

代码实现过程我们用了find函数和merge函数这两个最基本的(必须记下来)函数。

find函数可以实现,对每一个数都可以求出他的祖宗(根节点);而merge函数可以让树两两结合在一起,比如我们2出现了一次,那么我们就让2和(2+1)连接在一起,即把2挂在2+1上面,且fa[2]=fa[2+1](此时2+1的根节点就为自身)。这时又出现了1,同样的,我们把1挂在1+1=2上面,那么fa[1]=fa[1+1]=fa[2]=fa[2+1],这时若再出现1,那么输出fa[1]=fa[3]=3.在树的结构上,往前走一格刚好就是+1(从已经存在的点开始,沿着树枝的方向连续走,一直走到根节点的前一个,这些数都存在,所以都不能停,直到变成根节点,才符合题目要求)。


代码示例

def find(x):
    if x==fa[x]:
        return x
    else:
        fa[x]=find(fa[x])
        return fa[x]
def merge(x,y):
    fa[find(x)]=find(y)

if __name__=="__main__":
    n=int(input())
    ls=input().split()
    fa=[i for i in range(1000010)]
    for i in ls:
        a=int(i)
        b=find(a)
        print(b,end=" ")
        merge(b,b+1)
            

标签:__,函数,merge,python,查集,find,蓝桥,fa,节点
From: https://blog.csdn.net/weixin_71409897/article/details/137448435

相关文章

  • 差分和前缀和——蓝桥杯备赛
    一、大学里的树木要打药问题描述教室外有N棵树,根据不同的位置和树种,学校要对其上不同的药。因为树的排列成线性,且非常长,我们可以将它们看作一条直线给他们编号。树的编号从0∼N−1且N<1e6。对于树的药是成区间分布,比如3∼5号的树靠近下水道,所以他们要用驱蚊虫的药,20......
  • python UTF-8解码及脚本头的标注
    在Python中,如果你需要将编码为UTF-8的字节串解码为Unicode字符串,你可以使用内置的str类型的decode方法,或者使用bytes.decode()方法。但通常情况下,如果你已经在Python3中处理字符串,你可以直接将字节串(类型bytes)转换为字符串(类型str)。例如:python#假设我们有以下UTF-8编码的......
  • 蓝桥杯,省赛,动态规划专题,青蛙,更小的数,松散子序列,接龙数列
    #include<bits/stdc++.h>usingnamespacestd;constintN=1e5+9;doublex[N],a[N],b[N];doubledp[N][5];intmain(){intn;cin>>n;for(inti=1;i<=n;i++)cin>>x[i];for(inti=1;i<=n-1;i++)cin>>a[i]>>b[i......
  • Python算法学
    Python算法学习平台有很多,它们提供了丰富的资源和工具,帮助学习者从基础到高级的算法知识。以下是一些流行的Python算法学习平台:1.**LeetCode**:-网址:[https://leetcode.com/](https://leetcode.com/)-特点:LeetCode是一个非常受欢迎的在线编程平台,提供了大量的编程挑战,主......
  • 货币系统—背包问题—python题解
    题目链接:货币系统题目描述:给定V种货币(单位:元),每种货币使用的次数不限。不同种类的货币,面值可能是相同的。现在,要你用这V种货币凑出N元钱,请问共有多少种不同的凑法。输入格式第一行包含两个整数V和N。接下来的若干行,将一共输入V个整数,每个整数表示一种货币的......
  • 5G网络建设【华为OD机试】(JAVA&Python&C++&JS题解)
    一.题目-5G网络建设现需要在某城市进行5G网络建设,已经选取N个地点设置5G基站,编号固定为1到N,接下来需要各个基站之间使用光纤进行连接以确保基站能互联互通,不同基站之间架设光纤的成本各不相同,且有些节点之间已经存在光纤相连,请你设计算法,计算出能联通这些基站的最小成本是......
  • 项目排期【华为OD机试】(JAVA&Python&C++&JS题解)
    一.题目项目组共有N个开发人员,项目经理接到了M个独立的需求,每个需求的工作量不同,且每个需求只能由一个开发人员独立完成,不能多人合作。假定各个需求直接无任何先后依赖关系,请设计算法帮助项目经理进行工作安排,使整个项目能用最少的时间交付。输入描述:第一行输入为M个需......
  • 找城市【华为OD机试】(JAVA&Python&C++&JS题解)
    一.题目-找城市一张地图上有n个城市,城市和城市之间有且只有一条道路相连:要么直接相连,要么通过其它城市中转相连(可中转一次或多次)。城市与城市之间的道路都不会成环。当切断通往某个城市i的所有道路后,地图上将分为多个连通的城市群,设该城市i的聚集度为DPi(DegreeofP......
  • 电脑病毒感染【华为OD机试】(JAVA&Python&C++&JS题解)
    一.题目-电脑病毒感染一个局域网内有很多台电脑,分别标注为0-N-1的数字。相连接的电脑距离不一样,所以感染时间不一样,感染时间用t表示。其中网络内一个电脑被病毒感染,其感染网络内所有的电脑需要最少需要多长时间。如果最后有电脑不会感染,则返回-1给定一个数组times表示......
  • 两个字符串间的最短路径问题【华为OD机试】(JAVA&Python&C++&JS题解)
    一.题目-两个字符串间的最短路径问题给定两个字符串,分别为字符串A与字符串B。例如A字符串为ABCABBA,B字符串为CBABAC可以得到下图m*n的二维数组,定义原点为(0,0),终点为(m,n),水平与垂直的每一条边距离为1,映射成坐标系如下图。从原点(0,0)到(0,A)为水平边,距离为1,从(0,A)......