代码随想录算法训练营第61天 | 图论part08:拓扑排序+迪杰斯特拉朴素法
117.软件构建
https://kamacoder.com/problempage.php?pid=1191
拓扑排序精讲
https://www.programmercarl.com/kamacoder/0117.软件构建.html#拓扑排序的背景
47.参加科学大会
https://kamacoder.com/problempage.php?pid=1047
dijkstra(朴素版)精讲
https://www.programmercarl.com/kamacoder/0047.参会dijkstra朴素.html#思路
拓扑排序
-
拓扑排序是经典的图论问题:依赖关系是否成立
- 简述:一个有向图->线性排序
- 判断是否有环
-
方法:BFS(主要)和DFS
-
关键:找到入度为0的节点就是出发节点
-
主要步骤:
- 找到入度为0的节点,加入结果集;
- 将该节点从图中移除
点击查看代码
from collections import deque def main(): n,m = map(int,input().split()) ingree = [0]*n umap = [[] for _ in range(n)] res = [] ##构建邻接链表 for _ in range(m): s,t = map(int,input().split()) umap[s].append(t) ingree[t]+=1 ##找到入度为0的节点 queue = deque([]) for i in range(n): if ingree[i]==0: queue.append(i) ##遍历找到入度为0的节点 while queue: curr = queue.popleft() res.append(curr) files = umap[curr] if len(files)>0: for file in files: ingree[file]-=1 if ingree[file]==0: queue.append(file) if len(res)==n: print(" ".join(map(str,res))) else: print("-1") if __name__ == '__main__': main()
dijkstra(朴素版)精讲
-
三部曲
- 选择源点到哪个节点近 且 未被访问过;
- 该最近节点被标记访问过;
- 更新非访问节点到源点的距离(minDist数组);
-
minDist:源点到每个下一个点的最小值;选择最小值作为下一个点;
点击查看代码
def dijkstra(n, m, grid, start, end): mindist = [float("inf")]*(n+1) visited = [False]*(n+1) mindist[start] = 0 for i in range(1,n+1): minval = float("inf") curr = 1 for v in range(1,n+1): if not visited[v] and mindist[v]<minval: minval = mindist[v] curr = v visited[curr] = True for k in range(1,n+1): if not visited[k] and grid[curr][k]!=float("inf") and mindist[curr]+grid[curr][k]<mindist[k]: mindist[k] = mindist[curr]+grid[curr][k] if mindist[end]==float("inf"): return -1 else: return mindist[end] def main(): n,m = map(int,input().split()) grid = [[float("inf")]*(n+1) for _ in range(n+1)] for i in range(m): s,e,v = map(int,input().split()) grid[s][e] = v res = dijkstra(n,m,grid,1,n) print(res) if __name__ == '__main__': main()