最短路径
单源最短路径:
n个点到一个点的最短距离:建立反向图,
方法一,
Dijkstra算法:利用贪心思想,(不等处理负权的情况)
[dijkstra普通算法](记录详情 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))
[dijkstra堆优化算法](记录详情 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))
方法二:
Bellman-Ford算法:(不能处理负权回路)
原理:
每个点到起始点的最短距离都要经过(0 --- n-1)点,
通过第一次松弛操作,得到所有 到起始点经过0个点 的点的最短距离,
第二次松弛操作,得到所有 到起始点经过1个点 的点的最短距离
......
最后第n-1次松弛操作,得到所有 到起始点经过n-1个点 的点的最短距离
------------
进行第n次松弛操作,如果dis[i]发生改变,则表明第i个点到起始点要经过n个点,明显不成立,说明存在负环。
[bellman_ford算法模板](记录详情 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))
方法三:
SPFA算法,(Bellman-Ford的优化)
可能被一些数据针对,故意卡时间,导致Tle
使用队列优化
Bellman-Ford算法每次都遍历所有的边,而SPFA只遍历需要修改的边。
当一个点i的dis[i]被修改时,与i点相连的点才会被修改,其余点不做修改。
把与i相连的点放入队列,
持续做这种操作直到队列为空
[spfa算法模板](记录详情 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))
SPFA判断负环:
起始点到点i的距离,最多经过n-1条边
cut[n];//表示起始点到i点经过了几条边
进行松弛操作时,更新cut[i];
当cut[i]>=n时,存在负环。
多元最短路径:
Floyd算法:
O(n^3)
map[100][100];//表示i到j的距离
//k为中间节点
for (k = 1; k <= n; k++){//Floyd-Warshall算法核心语句
for (i = 1; i <= n; i++){
for (j = 1; j <= n; j++){
if (map[i][j] > map[i][k] + map[k][j])
{
map[i][j] = map[i][k] + map[k][j];
}
}
}
}
奇怪的异或和最短路: