Python之并查集 洛谷 蓝桥杯(2)

简介: Python之并查集 洛谷 蓝桥杯

但是这样超时 所以需要进行优化:


先分析超时的原因:还是利用上面给出的数组parent=[0,1,5,1,3,1,0,0](未合并)


我们可以画出下面这样的关系图:


所以科学家们给出了一种方法:路径压缩。


简言之,对于上图,比如在访问4的根节点的时候,经过图中标识的''很长''一段路径,这一段路径由许许多多的结点构成,它们有一个共同特点就是根节点都是1,那么路径压缩要做的就是把这条路径上的所有结点的父节点设为结点1


这样子的作用:比如我下一次查询结点3的根节点的时候,只需要1次,原来需要9999次!


def find_root(x):#返回根节点
    if x!=parent[x]:#只要不是根节点
        parent[x]=find_root(parent[x])#修改父节点为根结点
    return parent[x]#返回根节点(父节点)

第一次接触路径压缩如果不太好理解,可以先和小郑一样把这个模板记下来~


image.png


n,m,p=map(int,input().strip().split())
parent=[i for i in range(n+1)]
def find_root(x):#返回根节点
    if x!=parent[x]:#只要不是根节点
        parent[x]=find_root(parent[x])#把x的父节点设为根节点
    return parent[x]
def union(x,y):
    x_root=find_root(x)
    y_root=find_root(y)
    parent[x_root]=y_root
for i in range(m):
    tmp=list(map(int,input().strip().split()))
    union(tmp[0],tmp[1])
for j in range(p):
    tmp=list(map(int,input().strip().split()))
    if find_root(tmp[0])==find_root(tmp[1]):
        print('Yes')
    else:
        print('No')


image.png


可见路径压缩帮助我们优化了算法


蓝桥杯真题实战:七段码(第十一届试题E填空压轴)>>考察并查集


image.png


代码设计分析:题目就是在问一个连通性问题,从7条边选几个出来判断是不是连通图。


也就是判断是不是属于同一个集合的问题。首先明确一点,并查集两大功能:查找与合并。要先合并,再查找(没有合并一个集合那拿什么来查找?)。所以,相当于我们要先构建亲戚关系网,最后判断所有结点的祖先是否都是同一个,如果是则连通,否则不连通。


那么构建亲戚关系的条件:如果两个顶点直接相连,那么把那个点所属的集合与另外一个点所属的集合合并。当所有的点合并完了,只需要遍历所有的点的祖先,判断是否都是同一个,如果是,大功告成,count加1

def find_root(x):
    if x!=parent[x]:
        parent[x]=find_root(parent[x])
    return parent[x]
def union(x,y):
    x_root,y_root=find_root(x),find_root(y)
    if x_root!=y_root:
        parent[x_root]=y_root
edge=[[0]*7 for i in range(7)]#设一个0号进去,无边与其相连
l=[0,1,2,3,4,5,6]
edge[0][1]=edge[0][2]=edge[1][3]=edge[1][4]=edge[2][3]=1
edge[3][4]=edge[3][5]=edge[4][6]=edge[5][6]=edge[2][5]=1#有边相连记作1
for i in range(7):
    for j in range(7):
        edge[i][j]=max(edge[i][j],edge[j][i])#无向图对称
import itertools
count=0
for i in range(1,8):#灯泡数目
    for j in itertools.combinations(l,i):#比如[(1,2,3),[1,2,4]]
        parent=[i for i in range(7)]
        #判断两两是否连通
        for k in range(0,i):
            for p in range(k+1,i):
                if edge[j[k]][j[p]]==1:#如果连通,合并
                    union(j[k],j[p])
        for m in range(i-1):#判断属于是否同一集合(最终所有的)
            if find_root(j[m])!=find_root(j[m+1]):
                break
        else:
            print(j)#显示符合条件的数据,可删去
            count+=1
print(count)


#答案80


我是小郑 正在奔赴热爱 奔赴山海!


目录
相关文章
|
2月前
|
Python
蓝桥杯练习题(一):Python组之入门训练题
这篇文章是关于蓝桥杯Python组的入门训练题,包括Fibonacci数列、圆的面积、序列求和和A+B问题的具体代码实现和样例输出。
143 0
|
2月前
|
算法 开发者 计算机视觉
燃爆全场!Python并查集:数据结构界的网红,让你的代码炫酷无比!
在编程的世界里,总有一些数据结构以其独特的魅力和高效的性能脱颖而出,成为众多开发者追捧的“网红”。今天,我们要介绍的这位明星,就是Python中的并查集(Union-Find)——它不仅在解决特定问题上大放异彩,更以其优雅的设计和强大的功能,让你的代码炫酷无比,燃爆全场!
41 0
|
2月前
|
存储 机器学习/深度学习 算法
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
蓝桥杯Python编程练习题的集合,涵盖了从基础到提高的多个算法题目及其解答。
128 3
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
|
2月前
|
人工智能 Python
蓝桥杯练习题(四):Python组之历届试题三十题
关于蓝桥杯Python组历届试题的三十个练习题的总结,包括题目描述、输入输出格式、样例输入输出以及部分题目的解题思路和代码实现。
50 0
蓝桥杯练习题(四):Python组之历届试题三十题
|
2月前
|
Python
智慧之光!Python并查集:点亮你的编程思维,让复杂问题迎刃而解!
并查集以其简洁而强大的功能,成为了解决特定类型问题的首选工具。在编程的旅途中,掌握并查集不仅能帮助我们解决眼前的难题,更能点亮我们的编程思维,让我们在面对更复杂的问题时也能游刃有余。希望今天的分享能激发你对并查集的兴趣,让你在未来的编程道路上走得更远、更稳。
34 1
|
2月前
|
存储 算法 Python
火箭般的提升!学会Python并查集,让你的算法能力飞跃新高度!
火箭般的提升!学会Python并查集,让你的算法能力飞跃新高度!
37 1
|
3月前
|
Python
逆天改命!掌握Python并查集,数据结构难题从此不再是你的痛!
在编程旅程中,遇到棘手的数据结构难题是否让你苦恼?别担心,Python并查集(Union-Find)是你的得力助手。这是一种高效处理不相交集合合并及查询的数据结构,广泛应用于网络连通性、社交网络圈子划分等场景。通过维护每个集合的根节点,它实现了快速合并与查询。本文将介绍并查集的基本概念、应用场景以及如何在Python中轻松实现并查集,帮助你轻松应对各种数据结构挑战。
40 3
|
3月前
|
算法 计算机视觉 Python
Python并查集大揭秘:让你在算法界呼风唤雨,秒杀一切复杂场景!
在编程与算法的广袤天地中,总有一些工具如同神兵利器,能够助你一臂之力,在复杂的问题前游刃有余。今天,我们就来深入探讨这样一件神器——Python并查集(Union-Find),看看它是如何让你在算法界呼风唤雨,轻松应对各种复杂场景的。
82 2
|
2月前
|
存储 机器学习/深度学习 算法
蓝桥杯练习题(二):Python组之基础练习三十题
蓝桥杯Python编程练习题的集合,包含了三十个不同难度的编程题目,覆盖了基础语法、数据结构和算法等领域。
52 0
|
3月前
|
Python
告别低效!Python并查集:数据结构界的超级英雄,拯救你的编程人生!
告别低效!Python并查集:数据结构界的超级英雄,拯救你的编程人生!
34 0