C++ 基于Dijkstra算法和基于BFS算法的Ford Fulkson算法比较

本文介绍了如何使用C++分别基于Dijkstra算法和BFS算法实现Ford Fulkson最大流算法,并给出了一个样例输入及对应的最大流输出,强调了在不同情况下的运行效率。
摘要由CSDN通过智能技术生成

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<vector>
#include<queue>
#include<array>
#include<windows.h>

using namespace std;

const int INF = INT_MAX;


//Edmond Karp.
bool EK_bfs(vector<vector<int> > &G, int src, int dest, vector<int> &Pre) {
	vector<int> visited(G.size(), false);
	vector<int> _Pre(G.size(), -1);

	queue<int> Q;
	Q.push(src);
	visited[src] = true;

	while (!Q.empty()) {
		int nd = Q.front();
		if (nd == dest) break;
		
		Q.pop();

		for (int i = 0; i < G.size(); ++i) {
			if (!visited[i] && G[nd][i] > 0) {
				_Pre[i] = nd;
				Q.push(i);
				visited[i] = true;
			}
		}
	}

	Pre.swap(_Pre);
	if (Pre[dest] == -1) return false;
	else return true;

}

struct Node
{
	int dist;
	bool visited;
	Node() : dist(INF), visited(false) {}
};

bool Dijkstra(vector<vector<int> > &G, int src, int dest, vector<int> & Pre) {
	vector<Node> D(G.size());
	vector<int> _Pre(G.size(), -1);

	D[src].dist = 0;
	for (int i = 0; i < G.size() - 1; ++i) {
		//extract min
		int min = -1;
		for (int j = 0; j < G.size(); ++j) {
			if (!D[j].visited && (min == -1 || D[j].dist < D[min].dist))
				min = j;
		}
		
		if (D[min].dist == INF) break;
		else D[min].visited = true;

		//relax
		for (int j = 0; j < G.size(); ++j) {
			if (!D[j].visited && G[min][j] > 0
				&& D[j].dist > D[min].dist + G[min][j]) {
				D[j].dist = D[min].dist + G[min][j];
				_Pre[j] = min;
			}
		}
	}

	Pre.swap(_Pre);

	if (D[dest].dist == INF) return false;
	else return true;
}

int Max_flow(vector<vector<int> > & G, int src, int dest) {
	int mxf = 0;
	vector<int> Pre;
	while (Dijkstra(G, src, dest, Pre)) {
	//while (EK_bfs(G, src, dest, Pre)) {
		int minf = INF;
		
		int e = dest;
		while (Pre[e] != -1) {
			minf = min(minf, G[Pre[e]][e]);
			e = Pre[e];
		}

		e = dest;
		while (Pre[e] != -1) {
			G[Pre[e]][e] -= minf;
			G[e][Pre[e]] += minf;
			e = Pre[e];
		}

		mxf += minf;
	}

	return mxf;
}

int main(void) {
	int N, M;
	while (cin >> N >> M) {
		vector<vector<int> > G(N, vector<int>(N, 0));
		for (int i = 0; i < M; ++i) {
			int s, t;
			cin >> s >> t;
			cin >> G[s][t];		//G[s][t] > 0
		}

		int src, dest;
		cin >> src >> dest;

		int mx_f;

		LARGE_INTEGER t1, t2, tc;
		QueryPerformanceFrequency(&tc);
		QueryPerformanceCounter(&t1);
		
		mx_f = Max_flow(G, src, dest);
		
		QueryPerformanceCounter(&t2);
		printf("Use Time:%f\n", (t2.QuadPart - t1.QuadPart)*1.0 / tc.QuadPart);

		cout << "Max_flow: " << mx_f << endl;
	}
	system("pause");
	return 0;
}

输入样本:

6
8
0 1 2
0 2 3
1 3 3
1 4 1
2 3 1
2 4 1
3 5 2
4 5 3
0 5


样本输出:

Use Time:0.000168 (不同情况有不同结果)
Max_flow: 4



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值