本文主要摘自刘汝佳的《算法竞赛入门经典》,我只是加上看时的一些感悟。。
Bellman-Ford算法主要用于处理含负权的图,先证明下,如果含负权的图最短路存在,一定存在一个不含环的最短路。。
理由如下:
在边权可正可负的图中,环只有零环,正环和负环3种,如果包含零环或正环,去掉以后路径不会变长,如果包含负环,则意味着最短路不存在(因为可以无限跑负环)
既然不含环,最短路最多只可经过(起点不算)n-1个结点,可以通过n-1轮松弛操作得到//一:
先亮出代码:
for(int i=0;i<n;i++) { d[i]=inf; } d[0]=0; for(int k=0;k<n-1;k++)//循环次数n-1//二 { 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[i]); } } }
一:为什么Dijistra算法无法解决含负权的问题?
Dijkstra算法循环n次,每次循环都能够确定一个点的最短路,因为我们每次都是挑选d值最小的点,由于权为正,所以我们不可能通过d值比他大的点去走一走变得比他小。。。So,应该很好理解了
二:为什么Bellman-Ford算法循环n-1次,就能够确保最短路求解的正确呢?
我们假设循环n次的所求出来的最短路和循环n-1次所求出来的最短路不同,也就是说前面n-1次循环,每次循环都有松弛,第n次循环也有松弛。如果一个图没有负环的话任何一条最短路只会经过一个点最多一次,如果松弛n次说明至少被n个其他节点松弛过,则至少被某个结点松弛过2次,所以出现了负环,也就是说最短路不存在~~