117. 软件构建
思路:拓扑排序实际上不是一种排序方法,而是一种图论,用于解决如何排序多个事件。方法是记录每个事件的入度以及依赖关系。然后先进行入度为零的事件,同时将所有这个事件指向的事件入度减一。接着找剩下的入度为0的事件。而存储入度为0的事件就使用队列,用while queue来一直加入弹出入度为0的,直到最后队列为空。如果结果的长度等于事件数目,就说明成功完成排序,否则说明有循环依赖出现,输出-1
from collections import deque,defaultdict
n,m=map(int,input().split())
indegree=[0]*n
umap=defaultdict(list)
for _ in range(m):
s,t=map(int,input().split())
indegree[t]+=1
umap[s].append(t)
que=deque()
for i in range(n):
if indegree[i]==0:
que.append(i)
result=deque()
while que:
cur=que.popleft()
result.append(cur)
for end in umap[cur]:
indegree[end]-=1
if indegree[end]==0:
que.append(end)
if len(result)==n:
print(' '.join(map(str,result)))
else:
print(-1)
47. 参加科学大会dijkstra(朴素版)
思路:dijkstra和prim其实思路比较一致,也是分为三步,首先找到离出发点最近的点,之后将这个点标注为已经过,之后再更新从这个点到所有点的距离,看有没有比之前的距离近。整体上依然是n平方的复杂度,需要找n次最小的点,每次都先用n找最近的点,再用n遍历检查是否更新。需要注意的是,这里图中的所有权值必须都是非负的,原因是后面的新路径只能是原来的路径+新的距离,而由于所有权值非负,原来的路径已经在那一次比较中长于最短路径,加上新的距离依然不可能是最短的,而如果会有负权值的话,曾经走过的节点就不一定了。
n,m=map(int,input().split())
graph=[[float('inf')]*(n+1) for _ in range(n+1)]
for _ in range(m):
s,e,v=map(int,input().split())
graph[s][e]=v
minDist=[float('inf')]*(n+1)
visit=[False]*(n+1)
minDist[1]=0
visit[0]=True
for _ in range(n):
minval=float('inf')
cur=-1
for i in range(1,n+1):
if not visit[i] and minDist[i]<minval:
cur=i
minval=minDist[i]
if cur==-1:
break
visit[cur]=True
for i in range(1,n+1):
if not visit[i] and graph[cur][i]!=float('inf') and minDist[cur]+graph[cur][i]<minDist[i]:
minDist[i]=minDist[cur]+graph[cur][i]
if minDist[n]==float('inf'):
print(-1)
else:
print(minDist[n])
47. 参加科学大会dijkstra(堆优化版)
思路:在稀疏图上,如果用正常版本会有很多地方浪费掉。所以有两个优化的思路,一个是用邻接表代替邻接矩阵,另一个是用堆来存储每一个节点,可以自动弹出距离最近的节点,不需要重新寻找。堆使用的是heapq,添加的方法是heapq.heappush(堆名字,元组内容),排序的规则默认是元组中的第一个元素从小到大,弹出的方法是heapq.heappop()
import heapq
n, m = map(int, input().split())
graph = [[] for _ in range(n + 1)]
for _ in range(m):
s, e, v = map(int, input().split())
graph[s].append((e, v)) # 有向边 s->e
INF = float('inf')
minDist = [INF] * (n + 1)
visited = [False] * (n + 1)
pq = []
heapq.heappush(pq, (0, 1)) # (距离, 节点)
minDist[1] = 0
while pq:
dist, u = heapq.heappop(pq)
if visited[u]:
continue
visited[u] = True
for v, w in graph[u]:
if dist + w < minDist[v]:
minDist[v] = dist + w
heapq.heappush(pq, (minDist[v], v))
print(minDist[n] if minDist[n] != INF else -1)

222

被折叠的 条评论
为什么被折叠?



