目录点这里:【数据结构与算法】相关文章目录
Bellman-Ford算法 :
由于Dijckstra算法并不能用于计算带负权图的最短路径(原因),所以这里用Bellman-Ford算法来弥补这一缺点。
基本思想:前提:如果最短路存在,则最短路不存在环(正环零环可去掉,负环不存在最短路)。所以最短路最多包含n -1 个节点,所以只需要进行n -1轮松弛操作即可(松弛操作是什么:点这里)。复杂度为mn。
实现代码:(C++)
for(int i = 0; i < n; i++) d[i] = INF;
d[0] = 0;
for(int k = 0; k < n; k++)
for(int i = 0; i < m; i++) {
int x = u[i], y = v[i];
if(d[x] < INF) d[y] = min{d[y], d[x] + w[x][y]};
}
Floyd算法:
用于求每两对点之间的最短路,实现代码:
for(int k = 0; k < n; k++)
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
if(d[i][j] < INF && d[k][j] < INF) //如果点k连通i和j
d[i][j] = min{d[i][j], d[i][k] + d[k][j]}
拓展:在有向图中,如果设1为联通,0为不联通,并将” d[i][j] = min{d[i][j], d[i][k] + d[k][j]}“ 改成 ” d[i][j] = d[i][j] || (d[i][k] && d[k][j])“ ,就可以求道两点间是否联通,这样的结果称为有向图的传递闭包。
巧妙应用实例:噪音恐惧症(UVA10048 Audiophobia)
此题我发现了紫书上的一个题解错误(p365)题解中 “把加法修改成min, min 修改成 max” 应该改为 “把加法修改成max, min 不变”,不然一辈子做不对这道题。