代码随想录算法训练营day72 | 117. 软件构建、47. 参加科学大会

本次题目来自于卡码网

117. 软件构建(拓扑排序)

python设置默认值

from collections import defaultdict
aa = defaultdict(int)

拓扑排序:找到入度为0的节点,然后移除。如果最后都能移除,则无环,可以排序。

import collections
if __name__ == '__main__':
    n, m = map(int, input().strip().split())
    inDegree = [0] * n  # 记录每个文件的入度
    umap = collections.defaultdict(list)  # 记录文件依赖关系
    result = []  # 记录结果

    for _ in range(m):
        s, t = map(int, input().strip().split())
        inDegree[t] += 1  # t的入度加一
        umap[s].append(t)  # 记录s指向哪些文件

    queue = collections.deque()
    for i in range(n):
        # 入度为0的文件,可以作为开头,先加入队列
        if inDegree[i] == 0:
            queue.append(i)

    while queue:
        cur = queue.popleft()  # 当前选中的文件
        result.append(cur)
        files = umap[cur]  # 获取该文件指向的文件
        if files:  # cur有后续文件
            for i in range(len(files)):
                inDegree[files[i]] -= 1  # cur的指向的文件入度-1
                if inDegree[files[i]] == 0:
                    queue.append(files[i])

    if len(result) == n:
        print(" ".join([str(i) for i in result]))
    else:
        print(-1)

47. 参加科学大会(dijkstra算法)

最短路是图论中的经典问题即:给出一个有向图,一个起点,一个终点,问起点到终点的最短路径。

dijkstra算法:在有权图(权值非负数)中求从起点到其他节点的最短路径算法。

需要注意两点:

  • dijkstra 算法可以同时求 起点到所有节点的最短路径
  • 权值不能为负数

dijkstra算法和prim算法相似,都是分下面三步,但是变为了源点到节点的距离。

  1. 第一步,选源点到哪个节点近且该节点未被访问过
  2. 第二步,该最近节点被标记访问过
  3. 第三步,更新非访问节点到源点的距离(即更新minDist数组)
if __name__ == '__main__':
    n, m = map(int, input().strip().split())
    grid = [[float('inf')] * (n + 1) for _ in range(n + 1)]
    for i in range(m):
        p1, p2, val = map(int, input().strip().split())
        grid[p1][p2] = val

    start = 1
    end = n
    # 存储从源点到每个节点的最短距离
    minDist = [float('inf')] * (n + 1)

    # 记录顶点是否被访问过
    visited = [False] * (n + 1)

    minDist[start] = 0  # 起始点到自身的距离为0

    for i in range(1, n + 1):  # 遍历所有节点
        minVal = float('inf')
        cur = 1

        # 1、选距离源点最近且未访问过的节点
        for v in range(1, n + 1):
            if not visited[v] and minDist[v] < minVal:
                minVal = minDist[v]
                cur = v

        visited[cur] = True  # 2、标记该节点已被访问

        # 3、第三步,更新非访问节点到源点的距离(即更新minDist数组)
        for v in range(1, n + 1):
            if not visited[v] and grid[cur][v] != float('inf') and minDist[cur] + grid[cur][v] < minDist[v]:
                minDist[v] = minDist[cur] + grid[cur][v]

    if minDist[end] == float('inf'):
        print(-1)  # 不能到达终点
    else:
        print(minDist[end])  # 到达终点最短路径

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值