求容量网络的最大流,
输入:首先输入顶点个数n和弧数m,然后输入每条弧的数据,每条弧的数据格式为u v c f(分别表示起点、终点、容量和流量)。
源点为0,汇点为n-1。
输出:输出各条弧及其流量,以及求得的最大流流量。
*/
#include<stdio.h>
#include<string.h>
#include<math.h>
#define MAX 1000
#define INF 100000
#define MIN(a,b) ((a)<(b) ? (a):(b))
struct map{
int c,f;
}edge[MAX][MAX];
int m,n;
int flag[MAX]; //顶点的状态,-1未标号,0已标号未检查,1已标号已检查
int pre[MAX]; //标号的第一个分量:指明标号从哪个顶点得到,以便找出改进量
int alpha[MAX]; //标号的第二个分量,可改进量β
int queue[MAX]; //模拟队列
int qs,qe; //队列头和队列尾位置
int v; //从队列里取出来的队头元素
int i,j;
//寻找增广路
void BFS(){
memset(flag, 0xff, sizeof(flag)); //初始化为-1
memset(pre, 0xff, sizeof(pre));
memset(alpha, 0xff, sizeof(alpha));
flag[0] = 0; //源点初始化,已标号未检查
pre[0] = 0;
alpha[0] = INF;
qs = qe = 0;
queue[qe] = 0; //源点入队列
qe++;
while(qs<qe && flag[n-1]==-1){
v = queue[qs]; //取出队列头顶点
qs++;
for(i=0; i<n; i++){ //检查顶点v的正向和反向邻接点
if(flag[i] == -1){ //顶点未标号
if(edge[v][i].c<INF && edge[v][i].f<edge[v][i].c){//正向且未满
flag[i] = 0; //给顶点i标号(已标号未检查)
pre[i] = v;
alpha[i] = MIN(alpha[v],edge[v][i].c-edge[v][i].f);
queue[qe] = i; //顶点i入队列
qe ++;
}
else if(edge[i][v].c<INF && edge[i][v].f>0){//反向且有流量
flag[i] = 0; //给顶点i标号(已标号未检查)
pre[i] = -v;
alpha[i] = MIN(alpha[v], edge[i][v].f);
queue[qe] = i; //顶点i入队列
qe ++;
}
}
}
flag[v] = 1; //顶点i已标号已检查
}
}
//Ford_Fulkerson算法
void Ford_Fulkerson(){
while(1){
BFS();
if( alpha[n-1]==0 || flag[n-1]==-1 )
//当汇点没有获得标号,或者汇点调整量为0, 应该退出循环
break;
//当汇点有标号,应该进行调整
int k1=n-1, k2=abs( pre[k1] );
int a = alpha[n-1]; //可改进量
while(1){
if(edge[k2][k1].f <INF) //正向
edge[k2][k1].f = edge[k2][k1].f + a;
else //反向
edge[k1][k2].f = edge[k1][k2].f - a;
if(k2 == 0) //调整一直到源点v0
break;
k1 = k2;
k2 = abs( pre[k2] );
}
alpha[n-1] = 0;
}
}
//求最大流
void Max_flow(){int maxflow = 0;
for(i=0; i<n; i++){
for(j=0; j<n; j++){
if(i==0 && edge[i][j].f<INF)
maxflow += edge[i][j].f;
if(edge[i][j].f < INF)
printf("%d->%d:%d\n",i,j,edge[i][j].f);
}
}
printf("maxflow: %d\n",maxflow);
}
int main(){
int u,v,c,f;
scanf("%d%d",&n,&m);
for(i=0; i<n; i++)
for(j=0; j<n; j++)
edge[i][j].c = edge[i][j].f = INF;
for(i=0; i<m; i++){ //读入每条弧
scanf("%d%d%d%d",&u,&v,&c,&f);
edge[u][v].c = c; //构造邻接矩阵
edge[u][v].f = f;
}
Ford_Fulkerson();
Max_flow();
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
*/