最大流-Dinic算法
来源:互联网 发布:java redis list对象 编辑:程序博客网 时间:2024/05/20 06:29
Dinic算法
EK算法非常简单明了的解释了最大流的求流的过程,但是复杂度较高,所以需要更高级的算法来解决,没错,标题写着呢,Dinic算法。
Dinic算法的过程,只有两个,没错,也只有两个……(EK算法两个步骤:找增广路,对增广路上所有边加流量)
1.刷层次图
Dinic分为两个步骤:1.求层次图。2.求阻塞流。
1.求层次图
顾名思义,层次图是一层一层的,比如:
很明显用bfs就可以求出层次图(其实就是算出距离)。
2.求阻塞流
每次如果存在层次图(存在层次图等价于能从s到t),就在层次图中寻找增广路(只有i-1层的点才能到达i层),直到没有增广路为止。所有的这些增广路成为阻塞流。因为同时求很多增广路,所以我们可以用dfs实现。
不过有个当前弧优化:
每次把一个节点的所有能分配的流量都分光后,前面处理过的弧一定都是满载的(就是cap==flow),所以这些弧已经不需要处理,所以可以标一个数组lst[i]表示最后一次节点i处理到的弧。还有,如果当前所有流量已经分配完毕,直接退出,因为没法继续分,也就不会对答案有更多贡献。
模板
BZOJ 3396
本题有权限……不行的话用上面那道。
#include<cstdio>#include<cstring>#include<algorithm>#define maxn 60#define maxe 1405using namespace std;const int INF=(((1<<30)-1)<<1)+1;struct hdata{ int dad,j; hdata (int dad=0,int j=0):dad(dad),j(j){}}fa[maxn];int e,ans,tot,lnk[maxn],que[maxn],dst[maxn],cap[maxe],son[maxe],nxt[maxe],flow[maxe],lst[maxn];bool vs[maxn];void _add(int x,int y,int z){ son[++tot]=y; cap[tot]=z; flow[tot]=0; nxt[tot]=lnk[x]; lnk[x]=tot; son[++tot]=x; cap[tot]=0; flow[tot]=0; nxt[tot]=lnk[y]; lnk[y]=tot;}inline void readi(int &x){ x=0; char ch=getchar(); while ('0'>ch||ch>'9') ch=getchar(); while ('0'<=ch&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}}bool _bfs(){ memset(vs,0,sizeof(vs)); int hed=0,til=1; que[1]=1; vs[1]=true; dst[1]=0; while (hed!=til){ int x=que[++hed]; for (int j=lnk[x];j;j=nxt[j]) if (!vs[son[j]]&&cap[j]>flow[j]){ vs[son[j]]=true; dst[son[j]]=dst[x]+1; que[++til]=son[j]; } } return vs[26];}int _dfs(int x,int t,int now){ if (t==x||now==0) return now; int tem=0; for (int j=lst[x];j;lst[x]=j=nxt[j]) if (dst[x]+1==dst[son[j]]){ int ew=_dfs(son[j],t,min(now,cap[j]-flow[j])); if (ew){ flow[j]+=ew; flow[j^1]-=ew; tem+=ew; now-=ew; if (!now) break; } } return tem;}int getF(){ int tem=0; while (_bfs()){ for (int i=1;i<=52;i++) lst[i]=lnk[i]; tem+=_dfs(1,26,INF); } return tem;}int workc(){ char ch=getchar(); while (('a'>ch||ch>'z')&&('A'>ch||ch>'Z')) ch=getchar(); if ('a'<=ch&&ch<='z') return ch-'a'+27; else return ch-'A'+1;}int main(){ freopen("water.in","r",stdin); freopen("water.out","w",stdout); readi(e); tot=1; ans=0; memset(nxt,0,sizeof(nxt)); memset(lnk,0,sizeof(lnk)); for (int i=1,x,y,z;i<=e;i++){ x=workc(); y=workc(); readi(z); _add(x,y,z); } printf("%d\n",getF()); return 0;}
阅读全文
0 0
- Dinic算法最大流。。
- 最大流dinic算法
- 最大流 dinic算法
- 最大流 dinic算法
- 最大流-dinic算法
- 最大流-Dinic算法
- 最大流 Dinic算法
- 最大流算法 -- Dinic算法
- dinic算法 最大流 PKU1459
- 最大流dinic算法分析
- dinic 算法求最大流
- Dinic算法求最大流
- 最大流算法,Dinic,ISAP
- 最大流的Dinic算法
- 最大流模版Dinic算法
- 最大流 dinic算法模板
- 最大流 dinic算法 模板
- 最大流之Dinic算法
- springboot基础学习
- 技术不断突破 未来3年LoRa芯片将连续翻倍增长
- python pprint模块
- 解读The Python Tutorial(九)——类
- 想进一线互联网公司的应届生注意啦~2018 届校招的情况有些变化
- 最大流-Dinic算法
- list添加集合被覆盖,利用map求和——代码应该怎么放
- window.location.search实现页面跳转传参
- 一张表了解四大物联网通信技术差异:NB-IoT 、LTEeMTC、LoRa与SigFox
- Yii2.0-advanced-5—行为的使用(自动生成model时间数据)
- Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.apache.log4j.Log4jLoggerFa
- 为SaaS搜索引擎优化的3个技巧
- Gym Class(拓扑排序,STL应用)
- 使用Xcode9的Instruments检测解决iOS内存泄露