Bellman-Ford算法 C++/java实现 及优化

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 + " ");
    }
}

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/sinat_40477296/article/details/83239365
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞