博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
网络流之最大流问题
阅读量:4308 次
发布时间:2019-06-06

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

Reference:

http://blog.csdn.net/rrerre/article/details/6751520

http://blog.csdn.net/y990041769/article/details/21026445

http://www.nocow.cn/index.php/Translate:USACO/NetworkFlow

 

最大流Edmonds_Karp算法模板:

EK算法即增广路算法。

最大流最小割定理:最大流等于最小割

见白书P210

 

算法思想:

step 1. 令所有弧的流量为0,从而构造一个流量为0的可行流f(称作零流)。
step 2. 若f中找不到可改进路则转step 5;否则找到任意一条可改进路P。
step 3. 根据P求delta。
step 4. 以delta为改进量,更新可行流f。转step 2。
step 5. 算法结束。此时的f即为最大流。
算法的关键步骤是step 2,即:判断是否存在可改进路,若存在又如何求。
可以考虑用广度优先搜索。设置标志数组,记录顶点是不是被访问过;使用队列来存储已经访问过的顶点;另用一个一维数组p[i],记录每个顶点是由哪个顶点扩展而来(即记录父亲节点)。
首先S入队列。然后每次取队首顶点v,分析所有与v相邻的未访问顶点u:
1、存在弧<v, u>(正向弧),且u未访问。若f(v,u)<C(v,u)(非饱和弧),那么u入队列,给u打上“已访问”的标志,记u的父亲节点为v。
2、存在弧<u, v>(反向弧),且u未访问。若f(u,v) > 0(非零流弧),那么u入队列,给u打上“已访问”的标志,记u的父亲节点为-v。(以示和正向弧的区别)。
扩展完成后,若T还没有被访问就必然不存在可改进路;否则就从T出发,根据记录好的每个顶点的父亲节点信息,顺藤摸瓜,找出可改进路(同时还可以计算出delta)。

 

起点st,终点m

#include 
#include
#include
#include
using namespace std;int n,m,st,en;int cap[300][300]; //cap[u][v]:边(u,v)上的最大流量int flow[300][300]; //flow[u][v]:边(u,v)上当前的流量int a[300]; //a[u]:访问标记,同时还记录下delta值int p[300]; //记录父节点用const int inf=100000000;int EK() //st-->m{ queue
Q; memset(flow,0,sizeof(flow)); memset(p,-1,sizeof(p)); int f=0,minflow=inf; while(1) { memset(a,0,sizeof(a)); a[st]=inf; Q.push(st); while(!Q.empty()) { int u=Q.front();Q.pop(); for(int v=1;v<=m;v++) if(!a[v]&&cap[u][v]>flow[u][v]) { p[v]=u;Q.push(v); a[v]=a[u]
>n>>st>>m) //st->m { memset(cap,0,sizeof(cap)); for (int i=1;i<=n;i++) { cin>>S>>E>>C; cap[S][E]+=C;    //处理重边。有些题目,一条路上先给了容量30,然后重复了一次50,这时候这条路上的容量应该是30+50。 } cout<
<
View Code

 

模板例题:

hdu1532

 

补充:需要拆点的问题:POJ3281

http://www.2cto.com/kf/201210/164289.html

http://moxi466839201.blog.163.com/blog/static/18003841620112316351118/

 

-------------------------------------------------------------------------------------------

补充个ISAP模板,比EK算法快,但是难想难写。看不懂T^T...

#include 
#include
#include
#include
#include
using namespace std;typedef struct {
int v,next,val;} edge;const int MAXN=20010;const int MAXM=500010;edge e[MAXM];int p[MAXN],eid;void init(){memset(p,-1,sizeof(p));eid=0;}void insert1(int from,int to,int val) //有向{ e[eid].v=to;e[eid].val=val; e[eid].next=p[from]; p[from]=eid++; swap(from,to); e[eid].v=to;e[eid].val=0; e[eid].next=p[from]; p[from]=eid++;}void insert2(int from,int to,int val) //无向{ e[eid].v=to;e[eid].val=val; e[eid].next=p[from]; p[from]=eid++; swap(from,to); e[eid].v=to;e[eid].val=val; e[eid].next=p[from]; p[from]=eid++;}int n,m;//n为点数 m为边数int h[MAXN];int gap[MAXN];int s,t;int dfs(int pos,int cost){ if (pos==t) return cost; int j,minh=n-1,lv=cost,d; for (j=p[pos];j!=-1;j=e[j].next) { int v=e[j].v,val=e[j].val; if(val>0) { if (h[v]+1==h[pos]) { if (lv
=n) return cost-lv; if (lv==0) break; } if (h[v]
>m>>n) { init(); for(int i=0;i
View Code

 

补充:sap、isap(sap+gap优化)、dinic算法:

http://blog.csdn.net/sprintfwater/article/details/7913181

sap算法:

http://www.cnblogs.com/longdouhzt/archive/2011/09/04/2166187.html

转载于:https://www.cnblogs.com/pdev/p/3873789.html

你可能感兴趣的文章
TB创建公式应用dll失败 请检查用户权限,终极解决方案
查看>>
python绘制k线图(蜡烛图)报错 No module named 'matplotlib.finance
查看>>
talib均线大全
查看>>
期货市场技术分析06_长期图表和商品指数
查看>>
期货市场技术分析07_摆动指数和相反意见理论
查看>>
满屏的指标?删了吧,手把手教你裸 K 交易!
查看>>
不吹不黑 | 聊聊为什么要用99%精度的数据回测
查看>>
对于模拟交易所引发的思考
查看>>
高频交易的几种策略
查看>>
量化策略回测TRIXKDJ
查看>>
量化策略回测唐安奇通道
查看>>
CTA策略如何过滤部分震荡行情?
查看>>
量化策略回测DualThrust
查看>>
量化策略回测BoolC
查看>>
量化策略回测DCCV2
查看>>
mongodb查询优化
查看>>
五步git操作搞定Github中fork的项目与原作者同步
查看>>
git 删除远程分支
查看>>
删远端分支报错remote refs do not exist或git: refusing to delete the current branch解决方法
查看>>
python multiprocessing遇到Can’t pickle instancemethod问题
查看>>