时隔一个月,杂事也都差不多解决好了,新的学期新的开始。这是我初步学习网络流,为增广路问题做一个小的总结,以后有更好的模板再修改。
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
求最大流流量
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#define MAXN 1000 //顶点个数最大值
#define INF 1000000 //无穷大
#define MIN(a,b) ((a)<(b)?(a):(b))
struct ArcType
{
int c,f;//容量,流量
};
ArcType Edge[MAXN][MAXN];
int n,m; //顶点个数和弧数
int flag[MAXN]; //顶点的状态,三种
int pre[MAXN]; //标号的第一个分量
int alp[MAXN]; //标号的第二个分量,可改进两
int queue[MAXN]; //BFS,模拟队列
int v; //队头元素
int qs,qe; //对列头位置,队列尾位置
int i,j; //循环变量
void ford()
{
while(1)
{
memset(flag,0xff,sizeof(flag));
memset(pre,0xff,sizeof(pre));
memset(alp,0xff,sizeof(alp));
flag[0]=0;pre[0]=0;alp[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++)
{
if(flag[i]==-1)
{
if(Edge[v][i].c<INF && Edge[v][i].f < Edge[v][i].c)//正向
{
flag[i]=0;pre[i]=v;
alp[i]=MIN(alp[v],Edge[v][i].c-Edge[v][i].f);
queue[qe]=i; qe++;
}
else if(Edge[i][v].c<INF && Edge[i][v].f>0)//反向
{
flag[i]=0;pre[i]=-v;
alp[i]=MIN(alp[v],Edge[i][v].f);
queue[qe]=i; qe++;
}
}
}
flag[v]=1;
}
if(flag[n-1]==-1 || alp[n-1]==0)
break;
int k1=n-1,k2=abs(pre[k1]);
int a=alp[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)//到了源点
break;
k1=k2;k2=abs(pre[k2]);
}
}//end of while
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();
}