对于最短路径问题,Dijkstra算法只能求解所有边的权值都是非负的加权有向图,而Bellman-Ford算法虽然可以求解有负权值边的图的最短路径,但效率并不高。对于有向无环图,下面这种基于Dijkstra和拓扑排序的算法可以在线性时间内解决单点最短路径问题,且能够处理负权重的边,甚至能够求出最长路径。
该算法的思想很简单:按照拓扑顺序放松顶点。因为每条边v→w都只会被放松一次,当v被放松时有:dis[w] <= dis[v] + e.weight。在算法结束前该不等式都会成立,因为dis[v]是不会变化的(因为按照拓扑顺序放松顶点,在v被放松后算法不会再处理任何指向v的边)而dis[w]只会变小。因此,在所有从s可达的顶点都被加入到树中后,最短路径的最优性条件也就成立了。
结合拓扑排序算法和Dijkstra算法来求解有向无环图的最短路径可以在和V+E成正比的时间内得出结果。
//带权有向图
struct EdgeWeightedDigraph
{
size_t V; //顶点数
size_t E; //边数
map<int, forward_list<tuple<int, int, double>> adj; //改进后的邻接表,tuple存储的是边集
}
struct Comp
{
bool oper