這個算法實現比dijkstra+heap簡單,但是時間效率低一些 (O(VE))。可以判斷是否有負權的環。
算法的基礎是單源最短路問題中的path-relaxation property:設v_0到v_k的最短路為p={v_0, .... ,v_k},若p被relax的順序是(v_0, v_1),...,(v_k-1,v_k),則最后得到的v_0到p上各點的距離就是最短距離。
#include <iostream>
#define MAXN 200
#define INF 0xfffffff

using namespace std;

int list[MAXN][MAXN][2]; // 存儲圖,list[i][j][0]表節點編號,list[i][j][1]表節點i到list[i][j][0]的距離
int deg[MAXN]; // 各節點的出度
int n; // 節點數
int trace[MAXN]; // 存儲最短路
int d[MAXN]; // 算法結束時d[i]存源到節點i的最短距離

void initialize_single_source()


{
int i;
for(i=1;i<=n;i++) d[i]=INF;
d[1]=0;
}

void relax(int u,int v)


{
if(d[list[u][v][0]]>d[u]+list[u][v][1])

{
trace[list[u][v][0]]=u;
d[list[u][v][0]]=d[u]+list[u][v][1];
}
}

int bellman_ford()


{// 若存在負環返回-1;否則返回1
int i,j,k;
initialize_single_source();
for(i=0;i<n-1;i++)

{// 對所有邊relax n-1次
for(j=1;j<=n;j++)

{// 遍歷所有邊
for(k=0;k<deg[j];k++) relax(j,k);
}
}
// 檢查是否有負權的環
for(i=1;i<=n;i++)

{
for(j=0;j<deg[i];j++)

{
if(d[list[i][j][0]]>d[i]+list[i][j][1]) return -1;
}
}
//for(i=1;i<=n;i++) printf("%d distance:%d\n",trace[i],d[i]);
return 1;
}

void readdata()


{
int i,j;
scanf("%d",&n);
for(i=1;i<=n;i++)

{
scanf("%d",°[i]);
for(j=0;j<deg[i];j++)

{
scanf("%d%d",&list[i][j][0],&list[i][j][1]);
}
}
}

int main()


{
freopen("test.txt","r",stdin);
readdata();
printf("%d",bellman_ford());
return 1;
}