本次题目来自于卡码网
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的指向的文件入度-1if 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算法相似,都是分下面三步,但是变为了源点到节点的距离。
- 第一步,选源点到哪个节点近且该节点未被访问过
- 第二步,该最近节点被标记访问过
- 第三步,更新非访问节点到源点的距离(即更新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] = valstart = 1end = n# 存储从源点到每个节点的最短距离minDist = [float('inf')] * (n + 1)# 记录顶点是否被访问过visited = [False] * (n + 1)minDist[start] = 0 # 起始点到自身的距离为0for 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 = vvisited[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]) # 到达终点最短路径