网络流 之 一般增广路算法 标号法实现
来源:互联网 发布:linux ddos防御 编辑:程序博客网 时间:2024/05/22 03:16
数据输入格式:首先输入顶点个数n和弧数m,然后输入每条弧的数据。规定源点为顶点0,汇点为顶点n-1.每条弧的数据格式为:u,v,c,f,分别表示这条弧的起点,终点,容量和流量。顶点序号从0开始。
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <string>#include <map>#include <stack>#include <vector>#include <set>#include <queue>#pragma comment (linker,"/STACK:102400000,102400000")#define maxn 1005#define MAXN 1000#define mod 1000000009#define INF 0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-6typedef long long ll;using namespace std;struct ArcType//弧结构{ int c,f;//容量,流量};ArcType Edge[MAXN][MAXN];//邻接矩阵(每个元素为ArcType类型)int n,m; //顶点的个数和弧数int flag[MAXN]; //顶点状态:-1——未标号,0——已标号未检查,1——已标号已检查int prev[MAXN]; //标号的第一个分量:指明标号是从哪里得到的,以便找到可改尽量int alpha[MAXN]; //标号的第二个分量:可改进量int que[MAXN]; //队列int v; //从队列中取出来的队列头元素int qs,qe; //队列头位置,队列尾位置int i,j; //循环变量void ford(){ while (1) //标号直到不存在可改进路 { //标号前对顶点状态数组初始化为-1 memset(flag,-1,sizeof(flag)); memset(prev,-1,sizeof(prev)); memset(alpha,-1,sizeof(alpha)); flag[0]=0; prev[0]=0; alpha[0]=INF; //源点为已标号未检查点 qs=qe=0; que[qe]=0;//源点入队 qe++; //qs<qe表示队列非空,flag[n-1]==-1表示汇点未标号 while (qs<qe&&flag[n-1]==-1) { v=que[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;prev[i]=v; //给顶点i标号(已标号未检查) alpha[i]=min(alpha[v],Edge[v][i].c-Edge[v][i].f); que[qe]=i; //顶点i入队 qe++; } //"反向"且有流量 else if (Edge[i][v].c<INF&&Edge[i][v].f>0) { flag[i]=0; prev[i]=-v; //给顶点i标号(已标号未检查) alpha[i]=min(alpha[v],Edge[i][v].f); que[qe]=i; //顶点i入队 qe++; } } } flag[v]=1; } //end of while (qs<qe&&flag[n-1]==-1) //当汇点没有获得标号,或者汇点的调整量为零,应该退出while循环 if (flag[n-1]==-1||alpha[n-1]==0) break; //当汇点有标号时应该进行调整 int k1=n-1,k2=abs(prev[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) //调整一直到源点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);}int main(){ int u,v,c,f; //弧的起点,终点,容量,流量 while (scanf("%d%d",&n,&m)!=EOF) //读入顶点个数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(); } return 0;}/*6 100 1 8 20 2 4 31 3 2 21 4 2 22 1 4 22 3 1 12 4 4 03 4 6 03 5 9 34 5 7 2*/
23 0
- 网络流 之 一般增广路算法 标号法实现
- 网络最大流中一般增广路算法(标号法)
- 初识网络流(一般增广路算法-Ford-Fulkerson)
- 网络最大流之一般增广路方法------Ford-Fulkerson
- 网络流之增广路算法
- 网络流初步之最大流(增广路算法)
- 网络流之标号法
- 网络流DINIC增广路算法介绍
- 基于增广路的网络流算法
- 网络最大流求解 增广路算法
- 求最大流的使用距离标号的最短增广路算法
- 网络流增广路Edmonds-Karp算法(EK算法)代码实现
- 网络流之最大流的增广路径算法
- 增广路算法 Ford-Fulkerson算法 网络最大流问题
- 网络流增广路Edmonds-Karp算法 与 Dinic算法
- 图论最大网络流增广路算法详解与实现
- 网络流之 最短增广路算法模板(SAP)
- 网络流初步 增广路算法求最大流 hdoj3549
- 如何用Visio画数据库实体关系图
- Windows Socket 最大连接数(★firecat推荐★,附个人总结)
- HDU 1387 Team Queue 队列的模拟
- Servlet 3.0 proxool 配置 数据库连接池
- 二分查找,找到第一个符合条件的数字
- 网络流 之 一般增广路算法 标号法实现
- 题目1455:珍惜现在,感恩生活
- PoStartNextPowerIrp
- codeforce 342E 树链剖分 || 分块
- HDU 1846 Brave Game 博弈
- Dede小企业网站开发流程及常用标签(三)
- [归档]Ubuntu 14.04 安装tftp server
- xml字符串与map之间的相互转换
- cocos2dx快捷创建项目脚本