增广路算法 Ford-Fulkerson算法 网络最大流问题

#include<stdio.h>
#include<math.h>
#include<string>
#define MAXN 1000
#define INF 1000000


struct ArcType
{
	int c,f;
};

struct ArcType Edge[MAXN][MAXN];
int n,m;
int flag[MAXN];
int prev[MAXN];
int alpha[MAXN];
int queue[MAXN];
int v;
int qs,qe;
int i,j;

int MIN (int a,int b)
{return a<b?a:b;}

void ford()
{
	while(1)
	{
		memset(flag,-1,sizeof(flag));
		memset(prev,-1,sizeof(prev));

		flag[0]=0;
		prev[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++)
			{
				if(flag[i]==-1)
				{
					if(Edge[v][i].c<INF && Edge[v][i].f<Edge[v][i].c)
					{
						flag[i]=0;
						prev[i]=v;
						alpha[i]=MIN(alpha[v],Edge[v][i].c-Edge[v][i].f);
						queue[qe]=i;
						qe++;
					}
					if(Edge[i][v].c<INF && Edge[i][v].f>0)
					{
						flag[i]=0;
						prev[i]=-v;
						alpha[i]=MIN(alpha[v],Edge[i][v].f);
						queue[qe]=i;
						qe++;
					}
				}
			}
			flag[v]=1;
		}//end while 一次标记处理完毕

		if(flag[n-1]==-1 || alpha[n-1]==0)
			break;//大循环出口

		int k1=n-1;
		int k2=abs(prev[n-1]);
		int a=alpha[n-1];

		while(1)//对边的流量f进行整理
		{
			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(prev[k2]);
		}
	}

	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);
}

void 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();
	system("PAUSE");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值