基本原理 : 对于源点 v0 到某个点的最短距离,Bellman-Ford 算法对其进行了N-1 次的尝试松弛,一次松弛是指,对于一条边(u,v),判断v0到u的距离加上(u,v)的权值是否比v0到 v的最短距离短,如果是,则更新v0到v 的最短距离 .

       Bellman-Ford 算法的N-1次尝试中每次都对所有的E条边进行尝试松弛, 所以复杂度为O(NE),源点到每个点的最短路径中,最多经过除他们之外的N-2 个顶点 ,所以Bellman-Ford 算法对每个顶点进行N-1次松弛尝试, 如果没有负环出现,则最后一定可以确定源点到每个顶点的最短距离,包括有负边存在的情况下。如果要判断是否有负边环存在,可以运行第二次算法判断是否还能继续松弛,如果能,则存在负边环 . 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <vector>
const int MAX = 10005 ;
const int inf =0x3f3f3f3f ;

int dis[MAX] ;
struct Edge{
int u ;
int v ;
int w ;
};
Edge edge[MAX] ;
int n , m ;
bool Bellman_Ford(int src)
{
memset(dis,inf,sizeof(dis)) ;
dis[src] = 0 ;
for(int i = 0 ;i<n ; i++)
{
for(int j = 0 ;j<m ; j++)
{
if(dis[edge[j].u] + edge[j].w <dis[edge[j].v])
{
dis[edge[j].v] = dis[edge[j].u] + edge[j].w ;
}
}
}
// 判断是否存在负环
for(int i = 0 ;i<n ;i++)
{
for(int j = 0 ; j<m ;j++)
{
if(dis[edge[j].u] + edge[j].w <dis[edge[j].v])
{
return 1 ;
}
}
}

return 0 ;

}