3210. 最优灌溉+prim (python)

首先看一下数据范围,知道算法时间复杂度必须小于m**2。

要使图的整体权重加起来最小,那么肯定选(prim或者kru),论算法编写简单程度,肯定选prim。这题特别适合练习prim和kru,建议两种算法都使用一遍。

题目说没有重边和自环,平时写code时候需要注意这两点。

1.重边:两个点之间有两条以上的边连接

2.自环:一条线左右两端都连接一个点上

prim时间复杂度(nlogm),每个点都要遍历,并且需要用最小堆使得队列里的元素排序。

from collections import defaultdict
import heapq as pq

n, m = map(int,input().split())
edge = defaultdict(dict)
for _ in range(m):
    a, b, c = map(int,input().split())
    edge[a][b] = c
    edge[b][a] = c
ans = 0
vis = [0]*(n+1)
qu = [ [0, 1] ]
pq.heapify(qu)
while qu:
    spend, node = pq.heappop(qu)
    if vis[node]:continue
    vis[node] = 1
    ans += spend
    for nex in edge[node]:
        if vis[nex]:continue
        pq.heappush(qu, [edge[node][nex],nex])
print(ans)

kru时间复杂度(m),每个边都要遍历,从边中最小的两个点进行连线。

from collections import defaultdict
import heapq as pq

def find_f(x):
    if vis[x] == x:
        return x
    vis[x] = find_f(vis[x])
    return vis[x]

def kru():
    ans = 0
    # 把所有边都加进来排序
    edge.sort()
    # 初始化vis
    for i in range(1, n+1):
        vis[i] = i
    # 开始选择最小边连接
    for c, x, y in edge:
        x1 = find_f(x)
        y1 = find_f(y)
        if x1 != y1:
            vis[x1] = vis[y1]
            ans += c
    print(ans)
        
n, m = map(int,input().split())
edge = []
for _ in range(m):
    a, b, c = map(int,input().split())
    edge.append([c, a, b])

vis = [0]*(n+1)
kru()

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值