Dinic算法----最大流常用算法之一
——没有什么是一个BFS或一个DFS解决不了的;如果有,那就两个一起。
最大流的$EK$算法虽然简单,但时间复杂度是$O(nm^2)$,在竞赛中不太常用。
竞赛中常用的$Dinic$算法和$SAP$,其实也不太难。
那么,$Dinic$算法到底是什么呢?
多路增广
$Dinic$算法最核心的内容就是多路增广。
沿着$EK$算法的过程:

我们有一个图,如图一。
按照套路,我们先$BFS$,找$S-T$最短路。所有的距离标号都画在了图二上($EK$算法可能用不到,但$Dinic$用得到)。
假设我们选的是$S-3-T$这条路,增广。。。(如图三,绿色)
然后我们再来一遍$BFS$。。。 等等!
细心的你可能也发现了,$S-1-T$也是一条$S-T$最短路。
那就增广吧!(如图四)
您可以检查一下,这时候没有长度为$2$的最短路了。
但EK算法不会这样。它会再笨拙地$BFS$一遍,这就浪费了不少时间。
所以说,多路增广是很重要的。
我们换一种思路,如果网络流在一个$DAG$上,还不用考虑回退边,你会怎么做?
这很简单,$dfs$就能解决。
至于回退边。。。再来一次$BFS-DFS$就好了啊。
还有一个优化:当前弧优化:
对于每个点,我可能在一次$BFS$之后$DFS$多次。那么它出发的边所到的点里, 有些点出发已经满流。
这样, 我就可以每个点记录一个当前弧, 表示这次$DFS$它最后$DFS$到哪条弧,下次$DFS$它的时候就从这条弧开始。
这样,我就可以保证每条边在一次$DFS$中满流后不会再遍历。
这样的复杂度。。。理论上最坏是$O(n^2m)$,但这上界很松。
附代码!
int n;
struct Dinic{
struct Edge{
int from, to;
LL cap, flow;
Edge(int f = -, int t = -, LL c = )
:from(f), to(t), cap(c), flow()
{}
}edges[MAXM];
int next[MAXM], cnt;
int pre[MAXN], dis[MAXN];
int cur[MAXN]; //当前弧
Dinic()
{
memset(pre, -, sizeof(pre));
cnt = ;
}
void addedge(int f, int t, LL c)
{
edges[cnt] = Edge(f, t, c);
next[cnt] = pre[f];
pre[f] = cnt++;
edges[cnt] = Edge(t, f, );
next[cnt] = pre[t];
pre[t] = cnt++;
}
queue<int> Q;
bool BFS(int s, int t)
{
while(!Q.empty()) Q.pop();
memset(dis, -, sizeof(dis));
dis[s] = ;
Q.push(s);
while(!Q.empty())
{
int u = Q.front(); Q.pop();
for(int i = pre[u]; i >= ; i = next[i]) if(edges[i].cap > edges[i].flow)
{
int v = edges[i].to;
if(dis[v] >= ) continue;
dis[v] = dis[u] + ;
if(v == t) return true;
Q.push(v);
}
}
return false;
}
LL DFS(int now, int t, LL maxflow) //当前在now,汇点t
{ //最大可以提供maxflow的流量
if(now == t) return maxflow;
int ret = ;
for(int i = cur[now] != - ? cur[now] : pre[now]; i >= ; i = next[i]) if(edges[i].cap > edges[i].flow)
{
int v = edges[i].to;
if(dis[v] != dis[now] + ) continue;
int l = DFS(v, t, min(edges[i].cap - edges[i].flow, maxflow - ret));
ret += l;
edges[i].flow += l;
edges[i^].flow -= l;
cur[now] = i;
if(ret == maxflow) return ret;
}
cur[now] = -;
return ret;
}
LL solve(int s, int t)
{
int res = ;
while(BFS(s,t))
{
memset(cur, -, n * sizeof(int));
res += DFS(s, t, inf);
}
return res;
}
};
Dinic
代码可能有错,烦请指出。谢谢。
另外,如果有人知道些好用的画图软件麻烦推荐一下。用windows自带画图太累了。
Dinic算法----最大流常用算法之一的更多相关文章
- POJ1273 网络流-->最大流-->模板级别-->最大流常用算法总结
一般预流推进算法: 算法思想: 对容量网络G 的一个预流f,如果存在活跃顶点,则说明该预流不是可行流. 预流推进算法就是要选择活跃顶点,并通过它把一定的流量推进到它的邻接顶点,尽可能将正的赢余减少为0 ...
- 算法模板——Dinic网络最大流 2
实现功能:同Dinic网络最大流 1 这个新的想法源于Dinic费用流算法... 在费用流算法里面,每次处理一条最短路,是通过spfa的过程中就记录下来,然后顺藤摸瓜处理一路 于是在这个里面我的最大流 ...
- ACM常用算法及练习(2)
ACM常用算法及练习 知识类型 重要度 容易度 应掌握度 典型题 其他 数据结构(5) 链表 ★★☆ ★★★ ★★☆ 栈 stack ★★★ ★★★ ★★★ HLoj120 ...
- ACM常用算法及练习(1)
ACM常用算法及练习 第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码,因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打出来. 1.最短 ...
- ACM常用算法
数据结构 栈,队列,链表 哈希表,哈希数组 堆,优先队列 双端队列 可并堆 左偏堆 二叉查找树 Treap 伸展树 并查集 集合计数问题 二分图的识别 平衡二叉树 二叉排序树 线段树 一维线段树 二维 ...
- 总结Objective-c常用算法
今天是星期天,想睡到10点起床,结果认为自己太奢侈了,不能这么做,于是把闹钟设置成了6:30:结果终于9:36醒了,起床,无缘无故迟了,好吧,就算太累了吧,周天就原谅自己一回.终于到了中午 ...
- 【小白学游戏常用算法】二、A*启发式搜索算法
在上一篇博客中,我们一起学习了随机迷宫算法,在本篇博客中,我们将一起了解一下寻路算法中常用的A*算法. 通常情况下,迷宫寻路算法可以使用深度优先或者广度优先算法,但是由于效率的原因,不会直接使用这些算 ...
- Atitit 编程语言常用算法attilax总结
Atitit 编程语言常用算法attilax总结 1. 编译算法分类and 数据操作算法.1 1.1. Tab driver stat 状态转换表格算法1 1.2. Nest case 词法分析 ...
- js算法之最常用的排序
引入 大学学习计算机语言的那几年,从c语言,到c++,再到数据结构JAVA..让我印象最深刻的还是最开始老师讲冒泡算法的时候,直到现在大四快毕业了我才渐渐通窍了.刚学前端的时候以为前端就是做出好看很炫 ...
随机推荐
- 阿里云服务器之hexo环境搭建
上一步主要主要讲解云服务器购买和连接云服务器,以及文件的操作.本文主要讲解利用hexo搭建自己的静态博客,在服务器中建立自己的hexo博客环境,最后达到可以远程访问,以及远程git推送到github. ...
- git 命令摘录
回滚 n 个 commit (增加了revert commit) git revert -n commit_id 回滚到指定的commit_id(不增加commit,回滚的commit_id被删除) ...
- HDU-1260-Tickets(线性DP,DP入门)
Tickets Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Su ...
- 关于在JS中AJAX导致跨域问题的解决
在部署一个原声的前端项目的时候,请求该服务器后端接口时发现出现了CORS跨域的问题,但是服务端已经做了同源策略的兼容,常见问题,遂记录. 报错信息: XMLHttpRequest cannot loa ...
- Vue-cli 2.9 多页配置及多页面之间的跳转问题
vue开发,现在大部分做的都是(SPA)应用,但是,由于,需求不同,我们针对的用户需求变更较为,频繁,如果每次都全量打包更新,给开发的自测,及测试妹子的任务就会多,每次都要重新验证一下才放心.所以,想 ...
- 收集vcftools所有用法
VCFtools用来处理VCF文档. 筛选特定突变 比较文件 总结突变 转化文件格式 验证并合并文件 取突变交集和差集 Get basic file statistics input可以为VCF或BC ...
- mfix中输出DEM颗粒的固相速度到网格
基于mfix-19.1.2版本 方法一:直接输出差值网格固相速度 注:这种方式只适用于garg 2012颗粒差值格式在DEM中,默认是无法输出固相速度的网格值的: 但是通过搜索des文件夹下V_s关键 ...
- [LibreOJ #2983]【WC2019】数树【计数】【DP】【多项式】
Description 此题含有三个子问题 问题1: 给出n个点的两棵树,记m为只保留同时在两棵树中的边时连通块的个数,求\(y^m\) 问题2: 给出n个点的一棵树,另外一棵树任意生成,求所有方案总 ...
- 【App性能监控】:Android studio环境的搭建(以及遇到个各种坑)
今天搭建app性能测试环境,使用的是android studio的Android Device Monitor抓取trace日志分析: 1,下载最新的android studio安装,这一步没啥问题: ...
- Access network
1 State transfering A•Mobility:开机-搜寻PLMN/CELL来发现自己在网络中的位置•Attach request•Auth request•Auth res ...