算法特点:
-
可适用于负权重当且仅当不包含从源节点到达的负权重的环路
-
复杂度:O(V*E),效率低
算法流程
主要分为三部分:
- 初始化
- NodeNUm-1次循环,每次循环内部对每一条边做一次松弛操作
- 对每一条边检查是否存在负权重。通过松弛
实现代码:
#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 100
#define N 100
typedef struct edge {
int u,v;
int cost;
}Edge;
Edge edge[N];
int nodeNum,edgeNum,originalNode;
int dis[N],pre[N];
bool Bellman_Ford(){
// first step,intialization
for(int i = 1;i<=nodeNum;i++)
{
dis[i]=(i==originalNode)?0:MAX;
}
// second ste
for(int i=1;i<nodeNum;i++){
for(int j=1;j<=edgeNum;j++){
if(dis[edge[j].v]>dis[edge[j].u]+edge[j].cost){
dis[ edge[j].v ]=dis[edge[j].u]+edge[j].cost;
pre[ edge[j].v ] =edge[j].u;
}
}
}
// third step
bool flag=1;
for(int i=1;i<=edgeNum;i++){
if(dis[ edge[i].v ] > dis[ edge[i].u ] + edge[i].cost){
flag=0;
break;
}
}
return flag;
}
/*除了原点 每个下标对应为0,当路径存在,最后会到原点因为原点root=pre【root】而结束; 当路径不存在,pre对应值为0,而pre[0]==0,
所以结束。*/
void printPath(int root){
while(root!=pre[root]){
printf("%d-->",root);
root=pre[root];
}
if(root==pre[root]){
printf("%d\n",root);
}
}
int main(){
cout<<"Input nodeNum,edgeNum,originalNode:";
cin>>nodeNum>>edgeNum>>originalNode;
pre[originalNode]=originalNode;
cout<<"Input edges,like u,v,cost:\n";
for(int i=1;i<=edgeNum;i++){
cin>>edge[i].u>>edge[i].v>>edge[i].cost;
}
if(Bellman_Ford())
{
for( int i=1; i <=nodeNum; i++ )
{
cout<<"dis:"<<dis[i]<<endl;
cout<<"path:";
printPath(i);
}
}
else{
cout<<"there's nagative weight";
}
getchar();
return 0;
}