最大流 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值