博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
网络流常用算法
阅读量:5040 次
发布时间:2019-06-12

本文共 8784 字,大约阅读时间需要 29 分钟。

1.sap

递归版。

View Code
#include 
using namespace std;#define MAXN 10000struct Edge{ int v, next, val; Edge( ) { } Edge( int V, int N, int Val): v(V), next(N), val(Val) {} }edge[MAXN];int head[MAXN],size, flow, visit, sum, N, M, ans;int gap[MAXN], h[MAXN];/*sap算法核心:1.dfs搜索增广路2.标号 若存在v(i, j), 则h[i] = h[j] + 13.gap优化 若出现断层。。则结束 4.更新,正向更新,反向相减 */ void init( ){ for( int i = 0; i < MAXN; i++) { head[i] = -1; } size = 0; }void AddEdge( int u, int v, int val){ edge[size] = Edge(v, head[u], val); head[u] = size++; edge[size] = Edge(u, head[v], 0); head[v] = size++; }int dfs( int x, int flow = 0x7f7f7f7f){ if( x == N ) { return flow; } int v, u, high = N, f, tf = 0; for( v = head[x]; v != -1; v = edge[v].next ) { u = edge[v].v; if( edge[v].val > 0 ) { if( h[x] == h[u] + 1 && (f = dfs(u, min(flow - tf, edge[v].val)))) { edge[v].val -= f; edge[v^1].val += f; tf += f; if( h[1] >= N || tf == flow) return tf; } high = min(high, h[u]); } } if( tf == 0 ) { gap[h[x]]--; if( gap[h[x]] == 0 ) h[1] = N; h[x] = high + 1; gap[h[x]]++; } return tf; }void solve( ){ gap[0] = N; memset(h, 0, sizeof(h)); sum = 0; while( h[1] < N ) sum += dfs( 1 ); printf("Case %d: %d\n",++ans, sum); }int main( ){ int a, b, c, T; ans = 0; scanf("%d",&T); while( T-- ) { scanf("%d%d",&N, &M); init( ); for( int i = 1; i <= M; i++) { scanf("%d%d%d",&a, &b, &c); AddEdge(a, b, c); } solve( ); } return 0; }

 

2. sap非递归版

View Code
#include 
#include
using namespace std;#define MAXN 10000struct Edge{ int v, next, val; Edge( ) { } Edge( int V, int N, int Val): v(V), next(N), val(Val) { }}edge[MAXN];int head[MAXN], cur[MAXN], gap[MAXN], h[MAXN], path[MAXN], size, N, M, ans;queue
q;void init( ){ for( int i = 0; i < MAXN; i++) head[i] = -1; size = 0; }void AddEdge( int u, int v, int val){ edge[size] = Edge(v, head[u],val); head[u] = size++; edge[size] = Edge(u, head[v], 0); head[v] = size++; }void bfs( ){ q.push( N ); while( !q.empty() ) { int x = q.front(); q.pop( ); for( int u = head[x]; u != -1; u = edge[u].next) { int v = edge[u].v; if( h[v] == 0 && edge[u^1].val > 0) { gap[0]--; h[v] = h[u] + 1; gap[h[v]]++; q.push( v ); } } } }void sap( ){ memset(h, 0, sizeof(h)); memset(gap, 0, sizeof(gap)); for( int i = 0; i < MAXN; i++) { cur[i] = head[i]; path[i] = 0; } gap[0] = N; int u = 1, v, flow = 0x7f7f7f7f, high, sum = 0; path[u] = u = 1; while( h[1] < N ) { int f = 0; for( int &x = cur[u]; x != -1; x = edge[x].next ) { if( edge[x].val > 0 ) { int v = edge[x].v; int w = edge[x].val; if( h[u] == h[v] + 1 ) { path[v] = u; u = v; flow = min(flow, edge[x].val); f = 1; if( v == N ) { sum += flow; for( u = path[v] ; v != 1; v = u, u = path[u]) { edge[cur[u]].val -= flow; edge[cur[u]^1].val += flow; } flow = 0x7f7f7f7f; } break; } } } if( f ) continue; high = N; for( int t = head[u]; t != -1; t = edge[t].next ) { int w = edge[t].val; int v = edge[t].v; if( w > 0 ) { if( h[v] < high ) { high = h[v]; cur[u] = t; } } } gap[h[u]]--; if( gap[h[u]] == 0 ) h[1] = N; h[u] = high + 1; gap[h[u]]++; u = path[u]; } printf("Case %d: %d\n",ans++,sum);}int main( ){ int a,b,c,T; scanf("%d", &T); ans = 1; while(T--) { scanf("%d%d", &N, &M); init( ); for( int i = 0; i < M; i++) { scanf("%d%d%d",&a, &b,&c); AddEdge(a,b,c); } sap(); } return 0;}

 

3.dinic非递归版本

View Code
#include 
#include
using namespace std;#define MAXN 10610struct Edge{ int v, next, val; Edge( ) { } Edge(int V,int N, int Val): v(V), next(N), val(Val) { }}edge[MAXN];queue
q;int head[MAXN], h[MAXN], size, N, M, ans, cur[MAXN];int Q[106000];void init( ){ for( int i = 0; i < MAXN; i++) head[i] = -1; size = 0; }void AddEdge( int u, int v, int val){ edge[size] = Edge(v, head[u], val); head[u] = size++; edge[size] = Edge(u, head[v], 0); head[v] = size++; }int bfs( ){ memset( h, -1, sizeof(h)); q.push( 1 ); h[1] = 0; while( !q.empty()) { int x = q.front(); q.pop( ); for( int e = head[x]; e != -1; e = edge[e].next) { int w = edge[e].val; int v = edge[e].v; if( w > 0 && h[v] == -1) { h[v] = h[x] + 1; q.push( v ); } } } return h[N] != -1; }int dfs( ){ int e, u, v, w, p, i, sum = 0, f = 0; for( int i = 0; i <= N + 100; i++) cur[i] = head[i]; p = 1; Q[p] = 1; while( p ) { int x = Q[p]; if( x == N ) { int flow = 0x7fffffff; for( i = 1; i < p; i++) { x = Q[i]; e = cur[x]; if( edge[e].val < flow ) flow = edge[e].val; } int mid; for( i = 1; i < p; i++) { x = Q[i]; e = cur[x]; if( edge[e].val == flow ) mid = i; edge[e].val -= flow; edge[e^1].val += flow; } p = mid; sum += flow; continue; } for(e = cur[x]; e != -1; e = edge[e].next) { v = edge[e].v; w = edge[e].val; if( h[v] == h[x] + 1 && w > 0 ) { Q[++p] = v; break; } } cur[x] = e; if( e == -1 ) { p--; cur[Q[p]] = edge[cur[Q[p]]].next; } } return sum;}void solve( ){ int sum = 0; while( bfs( ) ) sum += dfs( ); printf("Case %d: %d\n",ans++,sum);}int main( ){ int a, b, c, T; scanf("%d",&T); ans = 1; while(T--) { scanf("%d%d",&N, &M); init( ); for( int i = 1; i <= M; i++) { scanf("%d%d%d",&a, &b, &c); AddEdge(a, b, c); } solve( ); } return 0; }

 

4.dinic递归版

View Code 
#include 
#include
using namespace std;#define MAXN 1010struct Edge{ int v, next, val; Edge( ) { } Edge(int V,int N, int Val): v(V), next(N), val(Val) { }}edge[MAXN];queue
q;int head[MAXN], h[MAXN], size, N, M, flow, visit, ans;void init( ){ for( int i = 0; i < MAXN; i++) head[i] = -1; size = 0; }void AddEdge( int u, int v, int val){ edge[size] = Edge(v, head[u], val); head[u] = size++; edge[size] = Edge(u, head[v], 0); head[v] = size++; }int bfs( ){ memset( h, -1, sizeof(h)); q.push( N ); h[N] = 0; while( !q.empty()) { int x = q.front(); q.pop( ); for( int e = head[x]; e != -1; e = edge[e].next) { int w = edge[e^1].val; int v = edge[e].v; if( w > 0 && h[v] == -1) { //printf("x = %d v = %d w = %d\n", x, v, w); h[v] = h[x] + 1; q.push( v ); } } } return h[1] != -1; }int dfs(int x, int flow = 0x7f7f7f7f){ if( x == N ) { return flow; } int e, tf = 0, f; for(e = head[x]; e != -1; e = edge[e].next) { int v = edge[e].v; int w = edge[e].val; if( h[x] == h[v] + 1 && w > 0 && (f = dfs(v, min(flow - tf, w))) ) { edge[e].val -= f; edge[e^1].val += f; tf += f; } } if( tf == 0) h[x] = -1; return tf;}void solve( ){ int sum = 0; while( bfs( ) ) sum += dfs(1); printf("Case %d: %d\n",ans++,sum);}int main( ){ int a, b, c, T; scanf("%d",&T); ans = 1; while(T--) { scanf("%d%d",&N, &M); init( ); for( int i = 1; i <= M; i++) { scanf("%d%d%d",&a, &b, &c); AddEdge(a, b, c); } solve( ); } return 0; }

转载于:https://www.cnblogs.com/tangcong/archive/2012/07/07/2580734.html

你可能感兴趣的文章
Oracle 存储过程简单语法
查看>>
程序员必须软件
查看>>
关于message pack as3 版本的一些修改。
查看>>
[G]java反射获得泛型参数getGenericSuperclass()
查看>>
数值函数ROUND(四舍五入),TRUNC(不四舍五入),MOD
查看>>
[毕业生的商业软件开发之路]开发第一个Windows应用程序
查看>>
AcWing 204. 表达整数的奇怪方式 (线性同余方程组)打卡
查看>>
web api 返回数据XML JSON
查看>>
Android端百度地图API使用详解
查看>>
NavigationBar设置
查看>>
IO端口和IO内存的区别及分别使用的函数接口
查看>>
夺命雷公狗---node.js---10之POST的接收
查看>>
自定义的JavaScript定时器
查看>>
smarty对数组进行json_encode
查看>>
Django model 字段类型及选项解析(二)
查看>>
《Linux命令行与shell脚本编程大全》第十四章 处理用户输入
查看>>
189. Rotate Array 从右边开始翻转数组
查看>>
用wget命令下载jdk
查看>>
python之路 Javascript的学习
查看>>
无法远程连接MySQL数据库服务器-(1130错误)
查看>>