网络流要满足的条件:(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;
}