Bellman-Ford最短路径和负圈判断

        Ballman-Ford的最短路径算法是以边为单位进行的,而Dijkstra则是以顶点为单位进行的啦。

        Ballman-Ford算法需要遍历所有|E|条边,最坏的情况下需要遍历|V – 1|*|E|条边,所以可以借助这个特点来判断图是否有负圈哦。

        Ballman-Ford能够解决带有负圈的图。

        时间复杂度为O(|E|*|V|)。

#include <stdio.h>
#include <string.h>

#define MAX_E 501
#define MAX_V 1001
#define INF 0xffffff

struct edge {
	int from, to;
	int cost;
};

edge e[MAX_E];
int lowcost[MAX_V];
int eCnt, vCnt;
int start, end;

void bellman(int s) {
	int i;
	bool update;

	for (i = 0; i <= vCnt; i++) {
		lowcost[i] = INF;
	}
	lowcost[s] = 0;

	while (true) {
		update = false;
		for (i = 0; i < eCnt; i++) {
			if (lowcost[e[i].to] > lowcost[e[i].from] + e[i].cost) {
				lowcost[e[i].to] = lowcost[e[i].from] + e[i].cost;
				update = true;
			}
		}

		if (!update) {
			break ;
		}
	}
}

bool findNegativeLoop() {
	int i, j;

	memset(lowcost, 0, sizeof(lowcost));
	for (i = 0; i < vCnt; i++) {
		for (j = 0; j < eCnt; j++) {
			if (lowcost[e[i].to] > lowcost[e[i].from] + e[i].cost) {
				lowcost[e[i].to] = lowcost[e[i].from] + e[i].cost;
				if (i == vCnt - 1) {
					return true;
				}
			}
		}
	}

	return false;
}

int main() {
	int i;

	printf("依次输入有向图{顶点数, 边数, 起点, 终点, 边(from, to, cost)}:\n");
	while (true) {
		scanf("%d%d%d%d", &vCnt, &eCnt, &start, &end);
		for (i = 0; i < eCnt; i++) {
			scanf("%d%d%d", &e[i].from, &e[i].to, &e[i].cost);
		}
		
		if (findNegativeLoop()) {
			printf("有负圈存在\n");
		} else {
			printf("无负圈存在\n");
		}

		bellman(start);
		
		printf("lowcost = %d\n", lowcost[end]);
	}

	return 0;
}

5 7 1 4
1 2 3
1 3 6
1 5 2
2 3 2
2 5 4
2 4 6
5 4 5

5 7 1 3
1 2 3
1 3 6
1 5 2
2 3 -1
2 5 4
2 4 6
5 4 5

5 7 1 4
1 2 -1
1 3 -4
1 5 -2
2 3 -3
2 5 -5
2 4 -6
5 4 -1

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