【技巧】浅谈Johnson算法

Johnson算法用于求解稀疏图上的全源最短路径问题。通过引入虚拟节点并利用SPFA算法预处理,该算法能有效避免负权边带来的复杂性,并通过Dijkstra算法找到所有顶点间的最短路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

Johnson算法主要用于求稀疏图上的全源最短路径。其主体思想是利用重赋权值的方法把一个原问题带负权的图转化为权值非负的图。然后再使用N次Dijkstra算法以求出全源最短路。
——姜碧野《PFA算法的优化与应用》

主要步骤

  1. 新建虚点S,S向每个点连边权为0的边;
  2. 以S为起点,跑全局SPFA,求出每个点到S的距离fxf_xfx
  3. 把每条边边权重赋值;

设从u到v的边权为w(u,v)w(u,v)w(u,v),重赋值以后就变成了:w′(u,v)=w(u,v)+fu−fvw'(u,v)=w(u,v)+f_u-f_vw(u,v)=w(u,v)+fufv
以下为原因:

设原来两点s,t之间最短路途径的点为s,x1,x2,x3.....,xk,ts,x_1,x_2,x_3.....,x_k,ts,x1,x2,x3.....,xk,t
di(s,t)=w(s,x1)+w(x1,x2)+w(x2,x3)+...+w(xk,t)di(s,t)=w(s,x_1)+w(x_1,x_2)+w(x_2,x_3)+...+w(x_k,t)di(s,t)=w(s,x1)+w(x1,x2)+w(x2,x3)+...+w(xk,t)
重赋值以后变成了:
di′(s,t)=w′(s,x1)+w′(x1,x2)+w′(x2,x3)+...+w′(xk,t)di'(s,t)=w'(s,x_1)+w'(x_1,x_2)+w'(x_2,x_3)+...+w'(x_k,t)di(s,t)=w(s,x1)+w(x1,x2)+w(x2,x3)+...+w(xk,t)
di′(s,t)=w(s,x1)+fs−fx1+w(x1,x2)+fx1−fx2+w(x2,x3)+fx2−fx3+...+w(xk,t)+fxk−ftdi'(s,t)=w(s,x_1)+f_s-f_{x_1}+w(x_1,x_2)+f_{x_1}-f_{x_2}+w(x_2,x_3)+f_{x_2}-f_{x_3}+...+w(x_k,t)+f_{x_k}-f_{t}di(s,t)=w(s,x1)+fsfx1+w(x1,x2)+fx1fx2+w(x2,x3)+fx2fx3+...+w(xk,t)+fxkft
di′(s,t)=w(s,x1)+w(x1,x2)+w(x2,x3)+...+w(xk,t)+fs−ftdi'(s,t)=w(s,x_1)+w(x_1,x_2)+w(x_2,x_3)+...+w(x_k,t)+f_s-f_tdi(s,t)=w(s,x1)+w(x1,x2)+w(x2,x3)+...+w(xk,t)+fsft
di′(s,t)=di(s,t)+fs−ftdi'(s,t)=di(s,t)+f_s-f_tdi(s,t)=di(s,t)+fsft
发现,fs−ftf_s-f_tfsft这个东西是不变的,所以可得原图中两点之间的最短路径不变;

又因为三角不等式,所以有fu+w(u,v)>=fvf_u+w(u,v)>=f_vfu+w(u,v)>=fv
所以:fu+w(u,v)−fv>=0f_u+w(u,v)-f_v>=0fu+w(u,v)fv>=0,可知重赋值后全局边权为非负数;

所以,这样处理完以后就可以愉快的跑DIJ了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值