代码随想录算法训练营第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(朴素版)精讲

  • 三部曲

    1. 选择源点到哪个节点近 且 未被访问过;
    2. 该最近节点被标记访问过;
    3. 更新非访问节点到源点的距离(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()
    
posted @ 2024-08-07 10:28  哆啦**  阅读(14)  评论(0编辑  收藏  举报