简介
Johnson算法主要用于求稀疏图上的全源最短路径。其主体思想是利用重赋权值的方法把一个原问题带负权的图转化为权值非负的图。然后再使用N次Dijkstra算法以求出全源最短路。
——姜碧野《PFA算法的优化与应用》
主要步骤
- 新建虚点S,S向每个点连边权为0的边;
- 以S为起点,跑全局SPFA,求出每个点到S的距离fxf_xfx;
- 把每条边边权重赋值;
设从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)+fu−fv;
以下为原因:
设原来两点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)+fs−fx1+w(x1,x2)+fx1−fx2+w(x2,x3)+fx2−fx3+...+w(xk,t)+fxk−ft
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)+fs−ft
di′(s,t)=di(s,t)+fs−ftdi'(s,t)=di(s,t)+f_s-f_tdi′(s,t)=di(s,t)+fs−ft
发现,fs−ftf_s-f_tfs−ft这个东西是不变的,所以可得原图中两点之间的最短路径不变;
又因为三角不等式,所以有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了。