最大流算法实现

/**********************
最大流算法
***********************/
#include <stdio.h>
#include <limits.h>
#define   abs(i)   ((i) <0)?(-(i)):(i)
#define   N   100
long   limits[N][N],last[N],flow[N][N],n,m;  
//limits数组记录容量,   flow记录流量
//   last记录某一点在增广路上的前趋:设为   i,   则正向弧标为   i,   反向弧标为-i
int   Init();
int   main()
{
                  long   i,j,k,used[N],v1,v2,cost,s,t,delta,sum;   //delta可改进的流量
                  while((scanf( "%ld%ld ",&n,&m))!=EOF)   //输入顶点数,   边数
                  {
                                    Init();
                                    s=1,t=n;     //   s为源点,   t为汇点
                                    for(i=0;i <m;i++)
                                    {
                                                      scanf( "%ld%ld%ld ",&v1,&v2,&cost);     //输入边及其相应的流量
                                                      limits[v1][v2]=cost;
                                    }
                                    while(1)
                                    {
                                                      for(i=1;i <=n;i++)used[i]=0,last[i]=0;
                                                      last[s]=INT_MAX;
                                                      while(last[t]==0)
                                                      {
                                                                        for(i=1;i <=n;i++)
                                                                                      if(last[i]&&!used[i])break;    
                                                                                      //找一个已标号但未使用过的点
                                                                        if(i> n)break;
                                                                        for(j=1;j <=n;j++)
                                                                                            if(!last[j])
                                                                                            {
                                                                                                              if(flow[i][j] <limits[i][j])                                                                                                                         last[j]=i;
if(flow[j][i])last[j]=-i;  
                                                                                              //找到点   i   的一个未被标号的后继
                                                                                            }
                                                                    used[i]=1;  
                                                        }     /*程序的核心:增广路的求法*/
                                                        if(last[n]==0)break;   //汇点未被标号,   则说明无增广路,   退出循环
                                                        for(i=n,delta=INT_MAX,k=INT_MAX;i!=1;)
                                                        {
                                                                        j=last[i];   //找可调整的流量
                                                                        if(j> 0)k=limits[j][i]-flow[j][i];
                                                                        else   k=flow[i][j];
                                                                        if(k <delta)delta=k;
                                                                        i=abs(j);
                                                        }
                                                        for(i=n;i!=1;)
                                                        {
                                                                          j=last[i];
                                                                          if(j <0)flow[i][j]-=delta;
                                                                          else   flow[j][i]+=delta;
                                                                          i=abs(j);
                                                        }   //调整流量,   使其满足流量图的性质
                                    }
                                    for(i=1,sum=0;i <=n;i++)
                                    {
                                                      if(flow[i][n])sum+=flow[i][n];
                                                      if(flow[n][i])sum-=flow[n][i];
                                    }   //   求最大流
                                    printf( "%ld/n ",sum);   //输出
                  }
                  return   0;
}
int   Init()
{
                  long   i,j;
                  for(i=1;i <=n;i++)
                                    for(j=i;j <n;j++)
                                    {
                                                      limits[i][j]=limits[j][i]=0;
                                                      flow[i][j]=flow[j][i]=0;   //初始化流量,   容量为   0
                                    }
                  return   0;
}

 

来自:http://topic.csdn.net/t/20051220/22/4471370.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值