网络流_Ford_Fulkerson

原创 2012年03月26日 12:34:01
/*
求容量网络的最大流,
输入:首先输入顶点个数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
*/

相关文章推荐

最大网络流的Ford-Fulkerson 算法

/**************************************************** > File Name: max_flow.cpp > Author: Yu...

《网络流学习笔记02--Edmonds-Karp,Ford-Fulkerson,Dinic三种算法实现最大流》

题目链接:click here 三种方法都用了一下,对比得出EK最少,只用46ms。 【Edmonds-Karp算法】 基础的最大流算法,每次BFS寻找最短路进行增广,找出一条残余路径就可以了。然后...

poj 1273 Drainage Ditches 【图论-网络流-最大流-Ford-Fulkerson】

Drainage Ditches Time Limit: 1000MS Memory Limit: 10000K Description Every tim...

初识网络流(一般增广路算法-Ford-Fulkerson)

这两天看了看求最大网络流的问题。着实有点费脑子。不过还好还是很有收获的。 在这里写的是关于通过找增广路求最大流的算法Ford-Fulkerson。算法的思路是通过BFS利用标记来找增广路。 具体过...

网络流问题Ford-Fulkerson算法详解

【转载推荐理由】:刚刚一直在看网络流问题Ford-Fulkerson算法的实现,正在疑惑为什么要添加反向边,一直不理解反向边在这个算法中至关重要的作用!而这片博客一开始举的这个例子可以帮助理解反向边的...

最大网络流(Ford-Fulkerson算法)(hihicoder)

Ford-Fulkerson算法          (有向图)         1.寻找一条从远点到终点的路径 2.找出这条路径里的最短边 3.将这条路径上的边减去 2 中求的最短边 ,其...
  • arz74
  • arz74
  • 2016年09月14日 18:06
  • 138

poj 1273 Drainage Ditches 网络流最大流入门 ford-fulkerson

Drainage Ditches Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 70072 ...

hihoCoder-第115周-网络流一·Ford-Fulkerson算法

题目链接点这里题目1 : 网络流一·Ford-Fulkerson算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述小Hi和小Ho住在P市,P市是一个很大很大的城...

poj 3281 Dining 【图论-网络流-最大流-EK&Ford-Fulkerson】

Dining Time Limit: 2000MS Memory Limit: 65536K Description Cows are such f...

网络流算法--Ford-Fulkerson方法及其多种实现

网络流 在上一章中我们讨论的主题是图中顶点之间的最短路径,例如公路地图上两地点之间的最短路径,所以我们将公路地图抽象为有向带权图。本章我们将对基于有向带权图的模型做进一步扩展。 很多系统中涉及流量...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:网络流_Ford_Fulkerson
举报原因:
原因补充:

(最多只允许输入30个字)