【学习笔记】 Johnson 全源最短路
前置扯淡 一年多前学的最短路,当时就会了几个名词的拼写,啥也没想过 几个月之前,听说了 “全源最短路” 这个东西,当时也没说学一下,现在补一下(感觉实在是没啥用) 介绍 由于 \(spfa\) 容易被卡,实际上我们在 \(O(nlog \space n)\) 的算法只有堆优化的 \(Dijkstra\) 由于先天问题, \(Dijkstra\) 无法处理在负权图上的问题 所以“ \(Johnson\) 全源最短路”算法就应运而生了 算法流程 我们针对 \(Dijkstra\) 无法处理负权图进行优化 我们考虑如何把每条边的权值转化成正数 这里引入 “势能” 的概念 势能需要一个起始点:建立一个虚拟源点(类网络流?),向每一个点连一条权值为 \(0\) 的有向边 跑一遍 \(spfa\) ,记录每个点到虚拟源点的最短路,记为 \(res[]\) (这里问显然 \(dis=0\) 的同学,请注意这可能是一个负权图) 然后我们把每一条边的边权操作一下: e[num].dis+=res[e[num].from]-res[e[num].to]; 这里 \(e[]\) 是前向星式建图 这样我们保证了每条边的权值都是正数(思考易得) 然后我们跑 \(n\) 次 \(Dijkstra\) ,最后 ans[from][to]-=res[from]-res[to]; 复杂度 \(O(n^2