网络流之 最短增广路算法模板(SAP)
来源:互联网 发布:淘宝号星级怎么算的 编辑:程序博客网 时间:2024/06/12 00:24
数据输入格式:首先输入顶点个数n和弧数m,然后输入每条弧的数据。规定源点为顶点0,汇点为顶点n-1.每条弧的数据格式为:u,v,w,分别表示这条弧的起点,终点,容量。顶点序号从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 2005#define mod 1000000009#define INF 0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-6typedef long long ll;using namespace std;int d[maxn]; //标号int mp[maxn][maxn]; //残留网络,初始为原图int num[maxn]; //num[i]表示标号为i的顶点数有多少int pre[maxn]; //记录前驱int n,m,s,t; //n个顶点,m条边,源点s,汇点tvoid init() //bfs计算标号,汇点t的标号为零{ int k; queue<int>Q; memset(d,INF,sizeof(d)); //初始化d数组为无穷大 memset(num,0,sizeof(num)); //初始化num数组num Q.push(t); //汇点t入队列 d[t]=0; //汇点标号为零 num[0]=1; //标号为0的顶点数为1 while (!Q.empty()) { k=Q.front(); Q.pop(); for (int i=0;i<n;i++) { if (d[i]>=n&&mp[i][k]>0) { d[i]=d[k]+1; Q.push(i); num[d[i]]++; } } }}int findAlowArc(int i) //从i出发寻找允许弧{ int j; for (j=0;j<n;j++) if (mp[i][j]>0&&d[i]==d[j]+1) return j; return -1;}int reLable(int i) //重新标号{ int mm=INF; for (int j=0;j<n;j++) if (mp[i][j]>0) mm=min(mm,d[j]+1); return mm==INF?n:mm;}int maxFlow(int s,int t) //求从源点s出发的最大流{ int flow=0,i=s,j; int delta; //增量 memset(pre,-1,sizeof(pre)); while (d[s]<n) { j=findAlowArc(i); if (j>=0) { pre[j]=i; i=j; if (i==t) //更新残留网络 { delta=INF; for (i=t;i!=s;i=pre[i]) delta=min(delta,mp[pre[i]][i]); for (i=t;i!=s;i=pre[i]) mp[pre[i]][i]-=delta,mp[i][pre[i]]+=delta; flow+=delta; } } else { int x=reLable(i); //重新标号 num[x]++; num[d[i]]--; if (num[d[i]]==0) //间隙优化 return flow; d[i]=x; if (i!=s) i=pre[i]; } } return flow;}int main(){ int u,v,c; //弧的起点,终点,容量 while (scanf("%d%d",&n,&m)!=EOF) //读入顶点个数n和弧数m { memset(mp,0,sizeof(mp)); for (int i=0;i<m;i++) { scanf("%d%d%d",&u,&v,&c); mp[u][v]=c; } s=0,t=n-1; init(); printf("%d\n",maxFlow(0,n-1)); } return 0;}/*6 100 1 80 2 41 3 21 4 22 1 42 3 12 4 43 4 63 5 94 5 7*/
29 0
- 网络流之 最短增广路算法模板(SAP)
- SAP最短增广路算法
- 最短增广路算法
- 最大流算法之EK(最短路径增广算法)
- templete_Dinic(最短增广路算法)
- 网络流之增广路算法
- 模板---图论:网络流增广路算法 Dinic
- 最大流的算法(EK算法)—>Edmonds-Karp算法(最短路径增广算法)
- 网络流,最基础的增广路算法!
- 最大流算法_最短增广算法
- 【网络流】【再次更新模板】SAP多路增广+GAP+当前弧
- 求最大流的使用距离标号的最短增广路算法
- 网络流初步之最大流(增广路算法)
- 网络流增广路(无费用)模板
- 网络流 之 一般增广路算法 标号法实现
- poj 1273 最大流之最短路径增广法(EK)
- 增广路算法(网络流) HDU1532 Drainage Ditches
- 初识网络流(一般增广路算法-Ford-Fulkerson)
- java多线程下载和断点续传
- no suitable driver found for jdbc:mysql//localhost:3306/..
- 第九周项目五——程序填充题(2)
- C++隐式类类型转换
- OVS+openflow+KVM
- 网络流之 最短增广路算法模板(SAP)
- tomcat access log pattern
- NSCharacterSet 简单用法
- C# 将MSMQ消息转换成Json格式 【优化】
- c# 未能加载文件或程序集
- 程序实践系列(八)继承与派生
- flex返回一条数据无法显示的问题
- 当return遇到finally
- 数据库--学习笔记2