最大流问题
最大流
最大流问题,是网络流理论研究的一个基本问题,求网络中一个可行流f*,使其流量v(f)达到最大, 这种流f称为最大流,这个问题称为(网络)最大流问题。最大流问题是一个特殊的线性规划问题,就是在容量网络中,寻找流量最大的可行流。
代码
#include <iostream>
#include <queue>
#include <string.h>
#include <stdio.h>
using namespace std;
const int MAXN = 205;
const int maxint = 0x3f3f3f;
int flow[MAXN][MAXN],maxflow[MAXN],father[MAXN];
int i,Maxflow,M,visit[MAXN];
//使用广度优先寻找到达目的的路径,节点里放当前找到的最小值,然后修改路径上的容量,类似于建双排车道
void ford_fulkerson()
{
queue<int>Q;int u,v;
Maxflow=0;//最大流初始化
while(1)
{
memset(maxflow,0,sizeof(maxflow));//每次寻找增广路径都将每个点的流入流量置为0
memset(visit,0,sizeof(visit));//标记一个点是否已经压入队列
maxflow[1]=INT_MAX; //源点的容量置为正无穷
Q.push(1); //将源点压入队列
while(!Q.empty()) //当队列不为空
{
u=Q.front();
Q.pop();
for(v=1;v<=M;v++) //M也是最后点序号
{
if(!visit[v]&&flow[u][v]>0)
{
visit[v]=1;
father[v]=u; //记录他的父亲方便往后的正反向更新
Q.push(v);
maxflow[v]=(maxflow[u]<flow[u][v]?maxflow[u]:flow[u][v]); //当前点的容量为父亲点容量与边流量的较小者
}
}
if(maxflow[M]>0) //如果找到了汇点并且汇点容量不为0则清空队列,不必等到队空。
{
while(!Q.empty())
Q.pop();
break;
}
}
if(maxflow[M]==0) //已经找不到汇点的增广路径了,就退出整个循环
break;
for(i=M;i!=1;i=father[i])
{
flow[father[i]][i]-=maxflow[M]; //正向更新
flow[i][father[i]]+=maxflow[M]; //反向更新
}
Maxflow+=maxflow[M]; //更新最大流
}
}
int main()
{
int N,si,ei,ci;
while(cin>>N>>M&&N!=EOF) //M定点个数,N 边数
{
Maxflow=0;
memset(flow,0,sizeof(flow));
for(i=0;i<N;i++)
{
cin>>si>>ei>>ci;
flow[si][ei]+=ci;
}
ford_fulkerson();
cout<<Maxflow<<endl;
}
cout << "Hello world!" << endl;
return 0;
}