首页 > 其他分享 >第十一章 图论 Part7

第十一章 图论 Part7

时间:2024-09-11 13:35:44浏览次数:8  
标签:图论 加入 第十一章 self 最小 距离 生成 Part7 节点

目录

最小生成树算法

prim算法

适用范围:无向图

思路

以将所有点归入最小生成树为目标,每次并入一个,最终生成最小生成树。
每次并入的步骤:

  1. 确定选哪个节点并入 (不在最小生成树里的,距离最小生成树(已并入的点)最小的节点) 遍历每个点,得到最小距离的那个点及最小距离。 (顶点编号)
  2. 将第一步选到的点加入到最小生成树中,用一个bool列表记录已经加入的点。
  3. 更新非生成树节点到生成树的距离。 (与cur相连的某节点的权值,比该节点距离最小生成树小 =》 因为cur加入最小生成树后,其他节点需要更新距离这个最新形成的部分最小生成树距离) =》 观察4这个节点随着各个节点的加入,距离最小生成树的最小值的变化;以及最终作为被选取的点加入到最小生成树的过程。

如果想记录这个最小生成树的边,则使用parent数组(元素值表示使当前节点更新的前一个节点),在第三步更新时记录即可,如果后续节点的加入还会使该点更新,则parent数组实际也会更新。



v,e = map(int,input().split()) # 顶点数,边数
graph = [[float('inf')]* (v+1) for _ in range(v+1)] #邻接矩阵

for _ in range(e):
    x,y,k = map(int,input().split())
    #无向图关于对角线对称,x到y的距离与y到x的距离相等
    graph[x][y] = k
    graph[y][x] = k

inTreePoints = [False]* (v+1) #是否加入到最小生成树中
minValVec = [float('inf')]* (v+1) #所有点的最小距离列表,初始化每个距离为10001

for i in range(1,v):  # 选完v-1个点,最后一个也确认了,它们一起构成最小生成树
    #1. 确认新加入的点的编号(谁距离最小生成树最近就加谁)
    cur = 1
    minDist = float('inf') #最大的权值 
    for j in range(1,v+1): #遍历所有还未加入最小生成树的点,确认要新加入的点的编号
         
        if not inTreePoints[j] and minValVec[j] < minDist:
            minDist = minValVec[j] #更新最小距离,以便在后续迭代中继续比较
            cur = j #更新新加入的点的编号,当循环退出时,确定新加入的点的编号
    
    #2.记录新加入的点
    inTreePoints[cur] = True
    
    #3.因为最小生成树有了新加入的点,更新每个未确定的点到部分最小生成树的最小距离
    for j in range(1,v+1):
        if (j not in inTreePoints and graph[cur][j] < minValVec[j]):#某点到最小生成树的距离可能由于最小生成树新加入了点而改变
            minValVec[j] = graph[cur][j]
    
    

res = 0
for i in range(2,v+1):
    res+=minValVec[i]

print(res)

kruskal算法

适用范围: 无向图

思路

以边为中心考虑,不断去添加最小的边合成一个集合(注意要添加不在一个集合的边,否则就是冗余边,会形成环),刚开始组成的图有可能是不连通的,但随着边的添加,最后一定会形成连通图,并且是最小连通子图即最小生成树,这种将点放入同一集合,判断点是否在同一集合中的逻辑,使用并查集来实现。下面简单给出算法(未给输入)。如果需要记录最小生成树的边,对于kruskal算法非常简单,join时添加当前边即可。

class UnionFind:
    def __init__(self,n):
        self.father = [0] * (n+1)
        for i in range(1,n+1):
            self.father[i] = i
        
    # (查) 
    def find(self,u): 
        if u == self.father[u]:
            return u
        else:
            self.father[u] = self.find(self.father[u])  # 路径压缩(一直像上层返回最底层的值,并且一直赋值)
            return self.father[u]
 
    # 判断 u 和 v 是否找到同一个根
    def is_same(self,u, v): 
        u = self.find(u)
        v = self.find(v)
        return u == v
 
    # 将 v->u 这条边加入并查集 (并)
    def join(self,u, v):
        u = self.find(u)  # 寻找 u 的根
        v = self.find(v)  # 寻找 v 的根
        if u == v:
            return  # 如果发现根相同,说明在一个集合,不用两个节点相连,直接返回
        self.father[v] = u #否则其中一根归于另一根

#kruskal算法
#1.按照边的权值由小到大排序
edges.sort(key=lambda x: x[2])
unionFind = UnionFind(v+1)

res = 0
for edge in edges:
  if not unionFind.is_same(edge[0],edge[1]):
    res += edge[2]
    join(edge[0],edge[1])   

标签:图论,加入,第十一章,self,最小,距离,生成,Part7,节点
From: https://www.cnblogs.com/haohaoscnblogs/p/18407924

相关文章

  • 代码随想录day 56 || 图论6
    Prim算法应用场景是主要是找到一个无向连通图的最小生成树,即连接所有节点且权重总和最小的树//prim三部曲//1,找到距离当前最小树最近节点//2,节点入树//3,更新mindist//更新树funcupdateMinDist(edges[][]int,nodeint){ for_,edge:=rangeedges{ ifed......
  • 代码随想录day55 || 图论5
    并查集197图中是否存在有效路径varfather[]intfuncvalidPath(nint,edges[][]int,sourceint,destinationint)bool{ //使用并查集算法,涉及到的操作,包括init,find,issample,join father=make([]int,n) fori,_:=rangefather{//init father[i]=i }......
  • 代码随想录训练营 Day53打卡 图论part04 110. 字符串接龙 105. 有向图的完全可达性 10
    代码随想录训练营Day53打卡图论part04一、卡码110.字符串接龙本题与力扣127题是一样的,所以这里使用力扣127题。字典wordList中从单词beginWord到endWord的转换序列是一个按下述规格形成的序列beginWord->s1->s2->…->sk:    每一对相邻的单词只......
  • 图论篇--代码随想录算法训练营第五十三天打卡| 110. 字符串接龙,105.有向图的完全可达
    110.字符串接龙题目链接:110.字符串接龙题目描述:字典strList中从字符串beginStr和endStr的转换序列是一个按下述规格形成的序列: 序列中第一个字符串是beginStr。序列中最后一个字符串是endStr。 每次转换只能改变一个字符。 转换过程中的中间字符串必须是字典......
  • 计算机三级 - 数据库技术 - 第十一章 故障管理 笔记
    第十一章故障管理内容提要:了解故障管理类型及数据库恢复技术了解数据转储技术了解如何利用日志文件进行数据恢复了解硬件容错方案11.1故障管理概述故障类型及解决方案:事务内部故障:导致数据不一致预期的事务内部故障:可通过事务过程本身发现解决办......
  • 第十一章 图论 Part4
    目录任务127.单词接龙思路Kama105.有向图的完全可达性思路463.岛屿的周长思路任务127.单词接龙字典wordList中从单词beginWord到endWord的转换序列是一个按下述规格形成的序列beginWord->s1->s2->...->sk:每一对相邻的单词只差一个字母。对于1<=i<=......
  • 图论板子
    Primtypedefpair<int,int>P;intprim(){intans=0,cnt=0;priority_queue<P,vector<P>,greater<P>>q;fill(d+1,d+n+1,INF);d[1]=0;q.push(P(d[1],1));while(!q.empty()&&cnt<......
  • 代码随想录day 53 || 图论4
    字符串接龙varqueue*list.ListvarvisitMapmap[string]boolfuncmain(){ varcountint fmt.Scanf("%d",&count) varstartStr,endStrstring fmt.Scanf("%s%s",&startStr,&endStr) varstrList=make([]string,count) fo......
  • 行政组织理论-第十一章:创建学习型组织
    章节章节汇总第一章:绪论第二章:行政组织的演变第三章:科层制行政组织理论第四章:人本主义组织理论第五章:网络型组织理论第六章:行政组织目标第七章:行政组织结构第八章:行政组织体制第九章:行政组织设置与自身管理第十章:组织激励第十一章:创建学习型组织第十二章:政府再造流程第十三......
  • 第十二章 图论 Part3
    目录任务Kama101.孤岛的总面积思路Kama102.沉没孤岛思路Kama103.水流问题思路Kama104.建造最大岛屿思路心得任务Kama101.孤岛的总面积给定一个由1(陆地)和0(水)组成的矩阵,岛屿指的是由水平或垂直方向上相邻的陆地单元格组成的区域,且完全被水域单元格包围。孤岛是那些位于矩......