使用Ford-Fulkerson 标号法求网络最大流。
#include
#include
#include
#include
#include
#include
#include
#define maxn 10010
#define INF 0xfffffff
using namespace std;
struct ArcType
{
int c,f;//容量、流量
};
ArcType edge[maxn][maxn];
int n,m;//顶点数、弧数
int flag[maxn];//顶点状态:-1——未标号;0——已标号未检查;1——已标号已检查
int prev[maxn];//标号的第一个分量:指明标号从哪个顶点而来,以便找出可改进量
int alpha[maxn];//标号的第二个分量:可改进量α
int que[maxn];//相当于BFS中的队列
int v;//队列头元素
int qs,qe;//队首队尾的位置
int i,j;
void ford()//标号法求网络最大流
{
while(1)//标号,直到不存在可改进路
{
memset(flag,-1,sizeof(flag));
memset(prev,-1,sizeof(prev));
memset(alpha,-1,sizeof(alpha));
flag[0]=0;
prev[0]=0;
alpha[0]=INF;
qs=qe=0;
que[qe]=0;//源点0入队列
++qe;
while(qs0)//反向且有流量
{
flag[i]=0;
prev[i]=-v;
alpha[i]=min(alpha[v],edge[i][v].f);
que[qe]=i;
++qe;
}
}
flag[v]=1;//标记顶点i已经检查
}
if(flag[n-1]==-1||alpha[n-1]==0) break;//汇点无标号或汇点的调整量为0
int k1=n-1,k2=abs(prev[k1]);
int a=alpha[n-1];//可改进量α
while(1)
{
if(edge[k2][k1].f"<>n>>m;//顶点个数、弧数
for(i=0; i>u>>v>>c>>f;
edge[u][v].c=c;//构造邻接矩阵
edge[u][v].f=f;
}
ford();
return 0;
}
/*
6 10
0 1 8 2
0 2 4 3
1 3 2 2
1 4 2 2
2 1 4 2
2 3 1 1
2 4 4 0
3 4 6 0
3 5 9 3
4 5 7 2
*/
void ford()//标号法求网络最大流
{
int flow[maxn][maxn];//节点之间的流量Fij
int prev[maxn];//可改进路径上前一个节点的标号,相当于标号的第一个分量
int minflow[maxn];//每个顶点的可改进量α,相当于标号的第二个分量
int que[maxn];
int qs,qe;//队列首尾位置坐标
int v,p;//当前顶点、保存Cij-Fij
for(i=0; i