首页 > 其他分享 >Leetcode 1135. 最低成本连通所有城市

Leetcode 1135. 最低成本连通所有城市

时间:2024-10-19 10:10:16浏览次数:1  
标签:node 连通 graph 最小 1135 节点 connection 权值 Leetcode

1.题目基本信息

1.1.题目描述

想象一下你是个城市基建规划者,地图上有 n 座城市,它们按以 1 到 n 的次序编号。

给你整数 n 和一个数组 conections,其中 connections[i] = [x_i, y_i, cost_i] 表示将城市 x_i 和城市 y_i 连接所要的cost_i(连接是双向的)。

返回连接所有城市的最低成本,每对城市之间至少有一条路径。如果无法连接所有 n 个城市,返回 -1

该 最小成本 应该是所用全部连接成本的总和。

1.2.题目地址

https://leetcode.cn/problems/connecting-cities-with-minimum-cost/description/

2.解题方法

2.1.解题思路

Prim算法求最小生成树

2.2.解题步骤

第一步,构建图的邻接表

第二步,根据Prim算法模板算出最小生成树的节点和最小权值和,判断最小生成树是否存在并返回结果

3.解题代码

Python代码

import heapq
from typing import Dict,List
# ==> Prim算法模板:用于计算无向图的最小生成树及最小权值和
# graph:无向图的邻接表;item项例子:{节点:[[相邻边的权值,相邻边对面的节点],...],...}
# return:minWeightsSum为最小生成树的权值和;treeEdges为一个合法的最小生成树的边的列表(列表项:[节点,对面节点,两点之间的边的权值]);visited:为最小生成树的节点,可以用来判断图中是否存在最小生成树
def primMinSpanningTree(graph:Dict[object,List[List]]):
    minWeightsSum,treeEdges=0,[]
    firstNode=list(graph.keys())[0]
    # 记录已经加入最小生成树的节点
    visited=set([firstNode])
    # 选择从firstNode开始,相邻的边加到堆中
    neighEdgesHeap=[item+[firstNode] for item in graph[firstNode]]
    heapq.heapify(neighEdgesHeap)
    while neighEdgesHeap:
        weight,node,node2=heapq.heappop(neighEdgesHeap) # node2为node的weight权值对应的边的对面的节点
        if node not in visited:    # 这个地方必须进行判断,否则会造成重复添加已访问节点,造成最小权值和偏大(因为前面遍历的节点可能将未遍历的共同相邻节点重复添加到堆中)
            minWeightsSum+=weight
            treeEdges.append([node,node2,weight])
            visited.add(node)
            # 遍历新访问的节点的边,加入堆中
            for nextWeight,nextNode in graph[node]:
                if nextNode not in visited:
                    heapq.heappush(neighEdgesHeap,[nextWeight,nextNode,node])
    return minWeightsSum,treeEdges,visited

class Solution:
    def minimumCost(self, n: int, connections: List[List[int]]) -> int:
        # Prim算法
        # 第一步,构建图的邻接表
        graph={i+1:[] for i in range(n)}
        for connection in connections:
            graph[connection[0]].append([connection[2],connection[1]])
            graph[connection[1]].append([connection[2],connection[0]])
        # print(graph)
        # 第二步,根据Prim算法模板算出最小生成树的节点和最小权值和,判断最小生成树是否存在并返回结果
        minWeightsSum,_,nodes=primMinSpanningTree(graph)
        return minWeightsSum if len(nodes)==n else -1

4.执行结果

在这里插入图片描述

标签:node,连通,graph,最小,1135,节点,connection,权值,Leetcode
From: https://www.cnblogs.com/geek0070/p/18475537

相关文章

  • 【leetcode】 码住—两种办法解决力扣数学思想 “加一” 操作
     前言......
  • LeetCode题练习与总结:最大单词长度乘积--318
    一、题目描述给你一个字符串数组 words ,找出并返回 length(words[i])*length(words[j]) 的最大值,并且这两个单词不含有公共字母。如果不存在这样的两个单词,返回 0 。示例 1:输入:words=["abcw","baz","foo","bar","xtfn","abcdef"]输出:16解释:这两个单词为"abc......
  • LeetCode题练习与总结:灯泡开关--319
    一、题目描述初始时有 n 个灯泡处于关闭状态。第一轮,你将会打开所有灯泡。接下来的第二轮,你将会每两个灯泡关闭第二个。第三轮,你每三个灯泡就切换第三个灯泡的开关(即,打开变关闭,关闭变打开)。第 i 轮,你每 i 个灯泡就切换第 i 个灯泡的开关。直到第 n 轮,你只需要切换......
  • LeetCode刷题日记之贪心算法(二)
    目录前言买卖股票的最佳时机II跳跃游戏跳跃游戏II总结前言在上一篇贪心算法的学习中,我们探讨了贪心算法的基本思路和逻辑框架。在这篇文章中,我将继续分享几道经典的LeetCode贪心算法题,并探讨其背后的解题思路和技巧。希望通过这些题目的实践,能加深我对贪心算法的理......
  • 闯关leetcode——112. Path Sum
    大纲题目地址内容解题代码地址题目地址https://github.com/f304646673/leetcode/tree/main/112-Path-Sum内容GiventherootofabinarytreeandanintegertargetSum,returntrueifthetreehasaroot-to-leafpathsuchthataddingupallthevalues......
  • 闯关leetcode——121. Best Time to Buy and Sell Stock
    大纲题目地址内容解题代码地址题目地址https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/内容Youaregivenanarraypriceswhereprices[i]isthepriceofagivenstockontheithday.Youwanttomaximizeyourprofitby......
  • 讲解LeetCode第150题:逆波兰表达式求值(完整代码)
    LeetCode第150题:逆波兰表达式求值题目介绍方法一:栈完整代码展示核心原理演示代码片段解释片段一:片段二:片段三:片段四:片段五:方法二:数组模拟栈完整代码展示核心原理演示代码片段解释片段一:片段二:片段三:......
  • Leetcode 721. 账户合并
    1.题目基本信息1.1.题目描述给定一个列表accounts,每个元素accounts[i]是一个字符串列表,其中第一个元素accounts[i][0]是名称(name),其余元素是emails表示该账户的邮箱地址。现在,我们想合并这些账户。如果两个账户都有一些共同的邮箱地址,则两个账户必定属于同一个人。请......
  • Leetcode刷题. 贪心算法
    贪心算法:    比较传统的解释:将整个问题拆解为几个小问题,找到小问题的最优解,加起来就是整个问题的全局最优解。对于现在的我理解贪心就是一种感觉,给出证明很难,解题思路一般就是认真读题,发掘题目的条件,然后尝试给出算法。11.盛最多水的容器     一个显而易......
  • LeetCode 209 - 长度最小的子数组(滑动窗口法)
    题目描述给定一个含有n个正整数的数组和一个正整数target,我们要找出该数组中满足其总和大于等于target的长度最小的子数组,即子数组[nums_left,nums_right],并返回其长度。如果不存在符合条件的子数组,返回0。解题思路我们可以使用滑动窗口解决这道问题。初始化左指针......