当前位置:网站首页>leetcode每周3道(八)图之最短路
leetcode每周3道(八)图之最短路
2022-06-22 06:04:00 【fire2fire2】
743. 网络延迟时间
题目描述
有 n 个网络节点,标记为 1 到 n。
给你一个列表 times,表示信号经过 有向 边的传递时间。 times[i] = (ui, vi, wi),其中 ui 是源节点,vi 是目标节点, wi 是一个信号从源节点传递到目标节点的时间。
现在,从某个节点 K 发出一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 -1 。
思路
题目实际是求节点 K 到其他所有点中最远的距离,那么首先需要求出节点 KK到其他所有点的最短路,然后取最大值即可。
- 单源最短路问题可以使用 Dijkstra 算法,其核心思路是贪心算法。流程如下:
- 首先,Dijkstra 算法需要从当前全部未确定最短路的点中,找到距离源点最短的点 x。
- 其次,通过点 xx更新其他所有点距离源点的最短距离。例如目前点 A 距离源点最短,距离为 3;有一条 A->B 的有向边,权值为 1,那么从源点先去 A 点再去 B 点距离为 3 + 1 = 4,若原先从源点到 B 的有向边权值为 5,那么我们便可以更新 B 到源点的最短距离为 4。
- 当全部其他点都遍历完成后,一次循环结束,将 xx 标记为已经确定最短路。进入下一轮循环,直到全部点被标记为确定了最短路。
代码转化:
- 首先,Dijkstra 算法需要存储各个边权,由于本题节点数量不超过 100100,所以代码中使用了邻接矩阵 graph[i][j] 存储从点 i 到点 j 的距离。若两点之间没有给出有向边,则初始化为 inf。
- 算法还需要记录所有点到源点的最短距离,代码中使用了 dist[i] 数组存储源点到点 i 的最短距离,初始值也全部设为 inf。由于本题源点为 K,所以该点距离设为 0。
- 其次,Dijkstra 算法需要标记某一节点是否已确定了最短路,在代码中使用了 visit[i] 数组存储,若已确定最短距离,则值为 true,否则值为 false。
代码实现
class Solution(object):
def networkDelayTime(self, times, n, k):
""" :type times: List[List[int]] :type n: int :type k: int :rtype: int """
#邻接矩阵的构建
graph = [[float('inf')] * n for _ in range(n)]
for x,y,w in times:
graph[x-1][y-1] = w
#原点到各个位置的最近距离矩阵
dist = [float('inf')] * n
dist[k-1] = 0
#访问flag数组
visit = [0]*n
#dijstra算法
for _ in range(n):
x = -1
#找到目前距离源点最近的点
for i,d in enumerate(dist):
if (not visit[i]) and (d<dist[x] or x == -1):
x = i
visit[x] = 1
#更新dist数组
for i,d in enumerate(graph[x]):
dist[i] = min(dist[i],dist[x]+d)
#当前距离原点最近的点x距离原点的距离为dist[x] 再加上x点距离i点的weight 进行更新
ans = max(dist)
return ans if ans != float('inf') else -1
结果

847. 访问所有节点的最短路径
题目描述
存在一个由 n 个节点组成的无向连通图,图中的节点按从 0 到 n - 1 编号。
给你一个数组 graph 表示这个图。其中,graph[i] 是一个列表,由所有与节点 i 直接相连的节点组成。
返回能够访问所有节点的最短路径的长度。你可以在任一节点开始和停止,也可以多次重访节点,并且可以重用边。
思路
- 由于题目需要我们求出「访问所有节点的最短路径的长度」,并且图中每一条边的长度均为 1,因此我们可以考虑使用广度优先搜索的方法求出最短路径。
- 在常规的广度优先搜索中,我们会在队列中存储节点的编号。对于本题而言,最短路径的前提是「访问了所有节点」,因此除了记录节点的编号以外,我们还需要记录每一个节点的经过情况。因此,我们使用三元组 (u,mask,dist) 表示队列中的每一个元素,其中:
u 表示当前位于的节点编号;mask 是一个长度为 nn 的二进制数,表示每一个节点是否经过。如果 mask 的第 i 位是 1,则表示节点 i 已经过,否则表示节点 i 未经过;dist 表示到当前节点为止经过的路径长度。- 这样一来,我们使用该三元组进行广度优先搜索,即可解决本题。初始时,我们将所有的 (i, 2^i, 0)放入队列,表示可以从任一节点开始。在搜索的过程中,如果当前三元组中的 mask 包含 n 个 1(即mask=2^n−1),那么我们就可以返回dist 作为答案。
细节
- 为了保证广度优先搜索时间复杂度的正确性,即同一个节点 u 以及节点的经过情况mask只被搜索到一次,我们可以使用数组或者哈希表记录(u,mask) 是否已经被搜索过,防止无效的重复搜索。
- bfs先到达的一定更优,这个常识,因为水波式扩散
- seen[v][mask_v]记录的是跑到v节点时状态为mask_v(通过状压记录状态,如果某个节点跑到过就让mask_v对应二进制位为1),而!seen[v][mask_v]则是看对于跑到当前节点v状态为mask_v的情况之前是否发生过,根据性质1,如果之前发生过,那么肯定之前的更优(准确说是不会更劣),那么用之前那个就可以,那当前这个情况就可以忽略了(这个也保证了不会绕圈圈)
- if (mask == (1 << n) - 1) {
ans = dist;
break;
}
也是根据性质1,如果所有点都被跑到过一次了,那么第一次达成该状态的跑法一定最优.
代码实现
class Solution(object):
def shortestPathLength(self, graph):
""" :type graph: List[List[int]] :rtype: int """
n = len(graph)
que = deque((i,1<<i,0) for i in range(n))
seen = {
(i,1<<i) for i in range(n)}
while(que):
u,mask,dist = que.popleft()
if mask == (1<<n)-1:
return dist
for v in graph[u]:
mask_v = mask | (1<<v)
if (v,mask_v) not in seen:
que.append((v,mask_v,dist+1))
seen.add((v,mask_v))
结果

边栏推荐
猜你喜欢

pip升级难题(已解决)You are using pip version 19.0.3, however version 22.1.2 is available.

小熊派BearPi-HM Micro正式合入OpenHarmony主干

Keil调试时设置断点的高级用法

Empirical mode decomposition (EMD) and Hilbert Huang transform (HHT)

No business series 7: removing spots from old photos

Single cell literature learning (Part2) -- stplus: a reference based method for the exact enhancement of St

Shengxin visualization (Part3) -- violin diagram

reduce_sum()中的reduction_indices

Ethernet UDP frame contract design

402 string (Title: Sword finger offer58 ii. left rotation string, 28. implementation of strstr(), 459 Repeated substrings)
随机推荐
osg编译osgQt
[technical notes]
pip升级难题(已解决)You are using pip version 19.0.3, however version 22.1.2 is available.
五大常考SQL面试题
Performance optimization best practices for reducing Game Size
电热水壶坏了别扔,它很容易修好的!
Modeling and Simulation of Radar Seeker Servo System
Empirical mode decomposition (EMD) and Hilbert Huang transform (HHT)
Use of idea plug-in EASYCODE
Ethernet communication protocol
Signal output library
Trigger
Ethernet UDP frame contract design
Conversion between gray code and binary
单细胞文献学习(part3)--DSTG: deconvoluting spatial transcriptomics data through graph-based AI
Single cell paper record (Part14) -- costa: unsupervised revolutionary neural network learning for St analysis
通过SMTP协议和Exchange两种方式实现邮件的发送功能
朗国科技助力OpenHarmony生态繁荣
pgsql批量插入
Research on dynamics and control of single ball robot

