最大流 C++实现

#include <iostream>
#include <queue>

using namespace std;

#define VERTEX 7 //顶点的个数
#define UINT_MAX 0xFFFF
//图
/
//        S   A   B   C   D   E   T
//	  S   0   3   1   0   0   0   0 
//    A   0   0   0   3   0   0   0
//    B   0   0   0   5   4   0   0
//    C   0   0   0   0   0   0   2  
//	  D   0   0   0   0   0   2   0
//	  E   0   0   0   0   0   0   3
//	  T   0   0   0   0   0   0   0


//保存流量
int capacity[VERTEX][VERTEX];

//是否已访问
bool visited[VERTEX];

//保存增广路径
int from[VERTEX];

//求最小值
int min(int x,int y){
	return x<y?x:y;
}


void init_capacity(){
	int i = 0;
	int j = 0;

	for(i=0;i<VERTEX;i++){
		for(j=0;j<VERTEX;j++){
			capacity[i][j] = 0;
		}
	}

	capacity[0][1] = 3;
	capacity[0][2] = 1;
	capacity[1][3] = 3;
	capacity[2][3] = 5;
	capacity[2][4] = 4;
	capacity[3][6] = 2;
	capacity[4][5] = 2;
	capacity[5][6] = 3;
}


void init_visited(){
	memset(visited,false,sizeof(visited));//不用for循环去遍历初始化
}

void init_from(){
	memset(from,-1,sizeof(from));
}

//广度优先搜索
int find_path(){
	int next;
	int where;
	int path_cap;
	int prev;
	queue<int> q;

	q.push(0);
	
	visited[0] = true;

	init_from();

	//找出一条增广路线
	
	while(q.empty()==false){
		where = q.front();
		q.pop();
		for(next=0;next<VERTEX;next++){
			//所有相邻节点
			if(!visited[next]&&capacity[where][next]>0){
				q.push(next);
				visited[next] = true;
				from[next] = where;
				if(next==VERTEX-1)
					goto now;//exit while
			}
		}
	}
now:
	//计算增广路线的最小流量
	where = VERTEX-1;
	path_cap = UINT_MAX;
	while(from[where]>-1){
		//前驱节点
		prev = from[where];
		path_cap = min(path_cap,capacity[prev][where]);
		where = prev;
	}

	//如果增广路径没找到或者path_cap是UINT_MAX
	if(path_cap == UINT_MAX)
		return 0;
	else return path_cap;
}

//计算最大流
int max_flow(){
	//最大流
	int result = 0;
	//每条路线的流量
	int path_capacity=0;

	while(true){
		//find_path返回找到的增广路线的流量,返回0表示没找到
		path_capacity=find_path();
		if(path_capacity==0){
			break;
		}else{
			result += path_capacity;
		}
	}

	return result;
}

void main(){
	init_capacity();
	init_visited();
	printf("%d\n",max_flow());
	return;
}


#include <iostream>
#include <queue>
#include <limits.h>

using namespace std;

#define VERTEX 7 //顶点的个数
#define UINT_MAX 0xFFFF
//保存流量
int capacity[VERTEX][VERTEX];

//是否已访问
bool visited[VERTEX];

//保存增广路径
int from[VERTEX];

typedef struct NODE{
	int vertex;
	int priority;
	int from;//存储前驱节点
}node,*pnode;

//求最小值
int min(int x,int y){
	return x<y?x:y;
}

void init_capacity(){
	int i = 0;
	int j = 0;

	for(i=0;i<VERTEX;i++){
		for(j=0;j<VERTEX;j++){
			capacity[i][j] = 0;
		}
	}

	capacity[0][1] = 3;
	capacity[0][2] = 1;
	capacity[1][3] = 3;
	capacity[2][3] = 5;
	capacity[2][4] = 4;
	capacity[3][6] = 2;
	capacity[4][5] = 2;
	capacity[5][6] = 3;
}


void init_visited(){
	memset(visited,false,sizeof(visited));//不用for循环去遍历初始化
}

void init_from(){
	memset(from,-1,sizeof(from));
}

//初始化节点
pnode init_node(int vertex,int priority,int from){
	pnode n;
	n = (pnode)malloc(sizeof(node));
	n->vertex = vertex;
	n->priority = priority;
	n->from = from;
	return n;
}

//priority-first search (PFS)
int find_path(){
	int where,cost;
	int new_cost;
	int path_cap;
	int next;
	int prev;//前驱节点

	priority_queue<pnode> pq;
	pq.push(init_node(0,UINT_MAX,-1));
	init_from();
	path_cap = 0;
	while(pq.empty()==false){
		pnode aux = pq.top();
		pq.pop();
		where = aux->vertex;
		cost = aux->priority;
		if(visited[where]) continue;
		from[where] = aux->from;
		if(where == VERTEX-1){
			path_cap = cost;
			break;
		}
		visited[where] = true;
		for(next=0;next<VERTEX;next++){
			if(!visited[next]&&capacity[where][next]>0){
				new_cost = min(cost,capacity[where][next]);
				pq.push(init_node(next,new_cost,where));
			}
		}
	}
	//更新残余网络
	where = VERTEX-1;
	while(from[where]>-1){
		prev = from[where];
		capacity[prev][where] -= path_cap;
		capacity[where][prev] += path_cap;
		where = prev;
	}
	return path_cap;
}

//计算最大流
int max_flow(){
	//最大流
	int result = 0;
	//每条路线的流量
	int path_capacity=0;

	while(true){
		//find_path返回找到的增广路线的流量,返回0表示没找到
		path_capacity=find_path();
		if(path_capacity==0){
			break;
		}else{
			result += path_capacity;
		}
	}

	return result;
}

void main(){
	init_capacity();
	init_visited();
	printf("%d\n",max_flow());
	return;
}





参考:http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=maxFlow

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个基于Ford-Fulkerson算法的最大网络算法的C++实现,其中使用了BFS来寻找增广路径: ```cpp #include <iostream> #include <queue> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 1005; const int INF = 0x3f3f3f3f; int n, m, s, t; // 网络中节点和边的数量,源节点和汇节点 int graph[MAXN][MAXN], parent[MAXN]; // 寻找增广路径 bool bfs() { memset(parent, -1, sizeof(parent)); queue<int> q; q.push(s); parent[s] = -2; while (!q.empty()) { int u = q.front(); q.pop(); for (int v = 0; v < n; ++v) { if (parent[v] == -1 && graph[u][v]) { parent[v] = u; if (v == t) return true; q.push(v); } } } return false; } // 计算最大网络 int max_flow() { int flow = 0; while (bfs()) { int path_flow = INF; for (int v = t; v != s; v = parent[v]) { int u = parent[v]; path_flow = min(path_flow, graph[u][v]); } for (int v = t; v != s; v = parent[v]) { int u = parent[v]; graph[u][v] -= path_flow; graph[v][u] += path_flow; } flow += path_flow; } return flow; } int main() { cin >> n >> m >> s >> t; memset(graph, 0, sizeof(graph)); for (int i = 0; i < m; ++i) { int u, v, w; cin >> u >> v >> w; graph[u][v] = w; } cout << "Max flow: " << max_flow() << endl; return 0; } ``` 其中,graph为网络的邻接矩阵表示,s为源节点的编号,t为汇节点的编号。函数max_flow()返回最大网络的大小。 在实现中,使用了一个bfs()函数来寻找增广路径,其返回值为bool类型。在每次循环中,都会调用bfs()函数来查找增广路径,如果找到了增广路径,则计算这条路径上的最小量,然后更新网络中的量。重复这个过程直到无法找到增广路径,此时最大网络的大小就是当前网络中的量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值