最大流

网络流要满足的条件:(1)除源source与汇sink外,其他节点上的注入必须等于流出;(2)各边上的实际流量不能大于容量。

从源发出的实际流量总和(或者说汇收到的实际流量总和)等于网络的流量。

 

#include<iostream>
#include<stack>
#include<vector>
#include<ctime>
using namespace std;

bool backtrack(int node_num,int **arr,stack<int> &sk,vector<int> &vc,int begin);
bool augpath(int node_num,int **arr);

int main(){
	/*根据用户输入,创建初始的图*/
	int **arr;
	int node_num=0;
	cout<<"Input the number nodes in the graph you want build:"<<endl;
	cin>>node_num;
	while(!node_num>3){
		cout<<"node numer must be an integer more than three.please input again:"<<endl;
		cin.get();
		cin>>node_num;
	}
	arr=new int*[node_num];
	for(int i=0;i<node_num;i++)
		arr[i]=new int[node_num];
	cout<<"please input v,w and f."<<endl<<"for example:2 3 75 means flow on arc(2,3) is 75."<<endl<<"Enter 0 to finish your input."<<endl;
	int s,t,f;
	while(cin>>s>>t>>f){
		if(!(s&&t&&f))
			break;
		arr[s-1][t-1]=f;
	}
	/*for(int i=0;i<node_num;i++){
		for(int j=0;j<node_num;j++)
			cout<<arr[i][j]<<"  ";
		cout<<endl;
	}*/
	
	/*不断寻找增广路径*/
	clock_t t1,t2;
	t1=clock();
	while(augpath(node_num,arr));
	/*for(int i=0;i<node_num;i++){
		for(int j=0;j<node_num;j++)
			cout<<arr[i][j]<<"  ";
		cout<<endl;
	}*/
	t2=clock();
	int res=0;
	for(int i=0;i<node_num;i++)
		res+=arr[i][0];
	cout<<"The maxflow of the graph is: "<<res<<endl;
	cout<<"Time consumed: "<<(float)(t2-t1)/CLOCKS_PER_SEC<<" seconds."<<endl;
	return 0;
}

bool backtrack(int node_num,int **arr,stack<int> &sk,vector<int> &vc,int begin){
	if(sk.empty())
		return false;
	int node=sk.top();
	if(node==node_num)
		return true;
	int i=begin;
	for(;i<node_num;i++){
		if(arr[node-1][i]!=0&&vc[i]==0){
			sk.push(i+1);
			//cout<<i+1<<"  ";
			vc[i]=1;
			break;
		}
	}
	if(i!=node_num)
		return backtrack(node_num,arr,sk,vc,0);
	else{
		cout<<endl;
		int last=sk.top();
		sk.pop();
		vc[last-1]=0;
		return backtrack(node_num,arr,sk,vc,last);
	}
}
bool augpath(int node_num,int **arr){
	/*用回溯法找到一条增广路径,若找不到就返回false*/
	bool found=false;
	stack<int> sk;				//保存已找到的路径节点。采用stack存储以方便回溯
	vector<int> vc(node_num,0);		//用于标记哪些节点已在stack中,1表示在,0表示不在
	sk.push(1);
	vc[0]=1;
	//cout<<endl<<1<<"  ";
	if(backtrack(node_num,arr,sk,vc,0)){
		found=true;
		int len=sk.size();
		for(int j=0;j<len-1;j++){
			int second=sk.top();
			sk.pop();
			int first=sk.top();
			arr[first-1][second-1]-=1;
			arr[second-1][first-1]+=1;
		}
	}
	return found;
}

 

posted @ 2010-11-03 17:02  张朝阳  阅读(241)  评论(0编辑  收藏  举报