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..让我印象最深刻的还是最开始老师讲冒泡算法的时候,直到现在大四快毕业了我才渐渐通窍了.刚学前端的时候以为前端就是做出好看很炫 ...
随机推荐
- HTML实例(四)
实例一:有序列表,无序列表,<dl>,<dt>,<dd>,div块级标签等,实现上面的效果. <!DOCTYPE html> <html lang ...
- java中的jdk配置详解:
1.配值系统变量"JAVA_HOME" 变量名JAVA_HOME: 指向:JDK(java开发工具包)的安装路径 目的:使用JDK安装目录时,可以直接通过”%JAVA_HOME%“ ...
- 在 iOS 中使用 iconfont
如何使用自定义字体 在讲icon font之前,首先先来看看普通自定义字体是如何在ios中使用的,两个原理是一样的.这里以KaushanScript-Regular为例: Step 1: 导入字体 ...
- C#-WebForm-Javascript、Jquery获取浏览器和屏幕各种高度宽度
Javascript: IE中:document.body.clientWidth ==> BODY对象宽度document.body.clientHeight ==> BODY对象高度d ...
- 下载 CentOS 7 镜像文件
CentOS 7 镜像文件的下载地址 CentOS 官网:https://www.centos.org/ 点击“Get CentOS Now” 点击想要下载的ISO镜像,(目前仅有“DVD ISO”和 ...
- 总纲篇:产品结构设计指导VII(本博客指引章节)
本章目的:搭建自己的产品结构设计知识体系与框架,从零开始设计一个完整产品. 需知远途即捷径! //作者的结构设计体系尚在搭建中,所有的文章都会定期进行一定编排修改 目录: 0)自序 1.基础篇 1)时 ...
- suse-Linux下安装Oracle11g服务器
系统要求 Linux安装Oracle系统要求 系统要求 说明 内存 必须高于1G的物理内存 交换空间 一般为内存的2倍,例如:1G的内存可以设置swap 分区为3G大小 硬盘 5G以上 2.修改操作系 ...
- windows下简单配置apache
不得不做个笔记,不然每次配置都记不清楚... 详细的配置朋友这边写的很好.地址 # 对 PHP 4 LoadModule php4_module "c:/php/php4apache2.dl ...
- WPF UpdateSourceTrigger属性
TextBox中的变化并不是立即传递到源,而是在TextBox失去焦点后,源才更新.这种表现由绑定中的UpdateSourceTrigger属性来控制.它的默认值是Default,源会根据你绑定的属性 ...
- CUBA与Spring相比,有很大的不同吗?
原文:Developing with CUBA - a big shift from Spring? 翻译:CUBA China CUBA-Platform 官网 : https://www.cuba ...