Bellman-Ford算法的核心就是对边进行松弛操作
贴上c++源代码
#include "stdafx.h"
#pragma warning(disable:4996)
#include <iostream>
using namespace std;
//表示一条边
struct Edge {
int src;
int dest;
int weight;
};
//带有权值的有向图
struct Graph {
int V;
int E;
Edge* edge;
};
//创建图
Graph* CreateGraph(int v, int e) {
Graph* graph = (Graph*)malloc(sizeof(Graph));
graph->E = e;
graph->V = v;
graph->edge = (Edge*)malloc(e * sizeof(Edge));
return graph;
}
//打印结果
void Print(int dist[], int n) {
cout << "单元最短路径" << endl;
for (int i = 0; i < n; i++) {
if (dist[i] == INT_MAX) {
cout << "与节点" << i << "距离->无穷大" << endl;
}//if
else {
cout << "与节点" << i << "距离->" << dist[i] << endl;
}
}
}
//单元最短路径
bool BellmanFord(Graph* graph, int src) {
int v = graph->V;
int e = graph->E;
//存储距离
int dist[100];
//初始化
for (int i = 0; i < v; i++) {
dist[i] = INT_MAX;
}
dist[src] = 0;
Edge edge;
int a, b, weight;
for (int i = 1; i < v; i++) {
for (int j = 0; j < e; j++) {
edge = graph->edge[j];
a = edge.src;
b = edge.dest;
weight = edge.weight;
if (dist[a] != INT_MAX && dist[a] + weight < dist[b]) {
dist[b] = dist[a] + weight;
}
}
}
//检测负权回路
bool isBack = false;
for (int i = 0; i < e; ++i) {
edge = graph->edge[i];
a = edge.src;
b = edge.dest;
weight = edge.weight;
if (dist[a] != INT_MAX && dist[a] + weight < dist[b]) {
isBack = true;
break;
}
}
Print(dist, v);
return isBack;
}
int main() {
int v = 7;
int e = 9;
Graph* graph = CreateGraph(v, e);
graph->edge[0].src = 0;
graph->edge[0].dest = 1;
graph->edge[0].weight = -1;
graph->edge[1].src = 0;
graph->edge[1].dest = 2;
graph->edge[1].weight = 4;
graph->edge[2].src = 1;
graph->edge[2].dest = 2;
graph->edge[2].weight = 3;
graph->edge[3].src = 1;
graph->edge[3].dest = 3;
graph->edge[3].weight = 2;
graph->edge[4].src = 1;
graph->edge[4].dest = 4;
graph->edge[4].weight = 2;
graph->edge[5].src = 3;
graph->edge[5].dest = 2;
graph->edge[5].weight = 5;
graph->edge[6].src = 3;
graph->edge[6].dest = 1;
graph->edge[6].weight = 1;
graph->edge[7].src = 4;
graph->edge[7].dest = 3;
graph->edge[7].weight = -3;
graph->edge[8].src = 5;
graph->edge[8].dest = 6;
graph->edge[8].weight = 2;
bool result = BellmanFord(graph, 0);
if (result) {
cout << "图中存在回路" << endl;
}//if
else {
cout << "图中不存在回路" << endl;
}//else
return 0;
}
通过邻接表表示图,用队列来优化
贴上代码
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
int dist[10010];
int book[10010];
int origin[10010], destination[10010], value[10010];
int n, m;
int total;
int next1[10010], head[10010];
void adl(int a, int b, int c)
{
total++;
origin[total] = a;
destination[total] = b;
value[total] = c;
next1[total] = head[a];
head[a] = total;
}
void Bellman_ford(int a) {
memset(book, 0, sizeof(book));//book[i]表示i号点是否在队列中
memset(dist, 88, sizeof(dist));
queue<int> q;
q.push(a);
book[a] = 1;
dist[a] = 0;
while (!q.empty()) {
for (int e = head[q.front()]; e; e = next1[e])
{
if (dist[destination[e]] > dist[origin[e]] + value[e]) {
dist[destination[e]] = dist[origin[e]] + value[e];
if (book[destination[e]] == 0) {
q.push(destination[e]);
book[destination[e]] = 1;
}
}
}
q.pop();
}
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= m; i++)
{
int a, b, c;
cin >> a >> b >> c;
adl(a, b, c);
}
Bellman_ford(1);
for (int i = 1; i <= n; i++)
cout << dist[i] << " ";
cout << endl;
return 0;
}
java源代码
import java.util.Scanner;
public class BellmanFord {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n;
int m;
int Inf = 999;
n = in.nextInt();
m = in.nextInt();
//初始化数据
int[] fromVertex = new int[m];
int[] toVertex = new int[m];
int[] weightVertex = new int[m];
int[] dis = new int[n];
int[] preNode = new int[n];
for (int i = 0; i < m; i++) {
fromVertex[i] = in.nextInt();
toVertex[i] = in.nextInt();
weightVertex[i] = in.nextInt();
}
//初始化dis
dis[0] = 0;
preNode[0] = 1;
for (int i = 1; i < n; i++) {
dis[i] = Inf;
}
boolean flag;
for (int k = 0; k < n - 1; k++) {
flag = true;
for (int i = 0; i < m; i++) {
if (dis[toVertex[i] - 1] > dis[fromVertex[i] - 1] + weightVertex[i]) {
dis[toVertex[i] - 1] = dis[fromVertex[i] - 1] + weightVertex[i];
preNode[toVertex[i] - 1] = fromVertex[i];
flag = false;
}
}
if (flag) {
break;
}
}
for (int i = 0; i < 5; i++) {
showPath(preNode, 1, i + 1);
System.out.println("距离: " + dis[i]);
}
}
public static void showPath(int[] path, int from, int to) {
int pre;
if (from == to) {
System.out.print(to + " ");
return;
}
pre = path[to - 1];
showPath(path, from, pre);
System.out.print(" " + to + " ");
}
}