Bellman算法
1.单源最短路径
2.有向图&无向图
3.边权可正可负(负权回路);
4.差分约束系统;
不断更新最短距离,若某次没有对Dist进行更新,说明最短路径已经查找完毕,或者部分点不可达,此时跳出循环。
struct edge{int from,to,cost};
edge es[N]; //边
int d[N],V,S; //最短距离,顶点数,边数
void bellman_ford(int s)
{
memset(d,INF,sizeof(d));
d[s]=0;
while(true)
{
bool update = false;
for(int i=0;i<E;i++)
{
edge e = es[i];
if(d[e.from] != INF && d[e.to]>d[e.from]+e.cost)
{
d[e.to]=d[e.from]+e.cost;
update = true;
}
}
if(!update) break;
}
}
负权回路,字面意思就是循环走一圈几个点,边权和为负数。由于我们想要求的是最短的路径,那么每个点都来跑一跑这个负权的回路岂不是路径会越来越短!这种状态下最短距离没有意义,所以显而易见,在我们跑完所有点的最短路径之后,再跑一次,如果检测到更新说明存在负权回路,保持不变则说明没有负权回路。
bool find_negative_loop() //返回true表示存在负环
{
memset(d,0,sizeof(d));
for(int i=0;i<V;i++)
{
for(int j=0;j<E;j++)
{
edge e=es[j];
if(d[e.to]>d[e.from]+e.cost)
d[e.to]=d[e.from]+e.cost;
if(i==V-1) //如果第n次仍然更新了,则存在负环
return truel
}
}
return false;
}