本人很弱,只会Dinic、EK与Ford-Fulkerson...(正在学习ISAP...)

这里讲Dinic...

Dinic:与Ford-Fulkerson和的思路相似(话说好像最大流求解都差不多吧),也是使用深搜寻找增广路(至于增广路是什么,只要在学最大流而不是借鉴他人代码的应该都知道吧)。

但是(划重点),Dinic有一个十分不一样的地方(Dinic:我们不一样,不一样!),就是还用了**BFS**(是为了凑齐深搜广搜召唤神龙)!

BFS有什么用呢,除了使时间复杂度更上一层楼之外,还有什么用呢?

这就是Dinic的神奇之处了,BFS反而使时间复杂度降低,与EK看似肩并肩(EK:O(nm^2) Dinic:O(n^2m))。看上去是肩并肩了,实则在题目上,Dinic基本都比EK优秀,特别是二分图。

扯远了,继续讲Dinic的BFS的用处。

BFS是为了划分等级(周朝的分封制!),使得在找增广路时跳过一些对这条增广路没用的点,使DFS效率大大提高。

另外,代码还可以加上当前弧优化与多路增广使其更快。

多路增广,设置一个变量used,记录这条边的流量,就不用搜到就退了,最后满了再退出。

当前弧优化:设置一个数组,在BFS预处理中将它赋值head[i],就相当于邻接表里的head,但是(划重点)它的值是随着增广的时候所变小的,然后下次增广时就可以跳过已经用过的边。

献上我丑陋的代码:

#include<cstdio>
#define INF 0x3f3f3f3f
#define maxn 3000001
inline int read(){//快读
int r=,f=;
char c=getchar();
while(c<''||c>''){
if(c=='-')f=-;
c=getchar();
}
while(c>=''&&c<=''){
r=r*+c-'';
c=getchar();
}
return r*f;
}
void write(int x)//快速输出
{
if(x<)
putchar('-'),x=-x;
if(x>)
write(x/);
putchar(x%+'');
}
struct edge{
int v,c,nxt;
}e[*maxn];
//struct max_Fow{//本来写了结构体的
int S,T,N,head[maxn],q[maxn],cur[maxn],level[maxn],tot=,hd,tl,v;
inline void init(int s,int t,int n){//为结构体而写
S=s;
T=t;
N=n+;
for(register int i=;i<N;i++)//想想为什么不直接为0
head[i]=-;
}
inline void add_edge(int u,int v,int c){
e[tot]=(edge){v,c,head[u]};//为什么从0开始?
head[u]=tot++;
}
inline void add(int u,int v,int c){
add_edge(u,v,c);
add_edge(v,u,);//反向边
}
inline bool BFS(){
for(register int i=;i<N;i++){
cur[i]=head[i];//当前弧优化初始化
level[i]=;//等级初始化
}
q[]=S;
level[S]=;
hd=;tl=;
while(hd^tl){//广搜
hd++;
for(register int i=head[q[hd]];i!=-;i=e[i].nxt){
if(e[i].c&&!level[e[i].v]){
tl++;
level[e[i].v]=level[q[hd]]+;
q[tl]=e[i].v;
if(e[i].v==T)return true;//搜到就退
}
}
}
return false;//否则无法拓展到汇点
}
inline int min(int a,int b){//手写min
if(a<b)return a;
return b;
}
int DFS(int f,int u){
if(u==T)return f;
int d=,used=;//多路增广
for(int &i=cur[u];i!=-;i=e[i].nxt){//当前弧优化
if(e[i].c&&level[u]==level[e[i].v]-){
if((d=DFS(min(f-used,e[i].c),e[i].v))){
e[i].c-=d;
e[i^].c+=d;//为什么可以直接这样?
used+=d;//多路增广
}
}
}
if(!used)level[u]=;
return used;
}
inline int Dinic(){//求解
int max_flow=;
while(BFS()){
int d=;
while((d=DFS(INF,S)))
max_flow+=d;
}
return max_flow;
}
//}Flow;
int main(){
int n=read(),m=read(),s=read(),t=read(),i;
/*Flow.*/init(s,t,n);
for(i=;i<=m;i++){
int a=read(),b=read(),v=read();
/*Flow.*/add(a,b,v);
}
int ans=/*Flow.*/Dinic();
write(ans);
return ;
}

Q:为什么head[]初始值为-1更好?

A:因为开始值就会为0,xor1就等于+1或-1,那样又会少了一些判断,

并且,Dinic也可以做费用流,只要将广搜换为SPFA就行了

完结撒花!!!✿✿ヽ(°▽°)ノ✿

题解 洛谷 P3376 【【模板】网络最大流】的更多相关文章

  1. 【最大流ISAP】洛谷P3376模板题

    题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...

  2. P3376 [模板] 网络最大流

    https://www.luogu.org/blog/ONE-PIECE/wang-lao-liu-jiang-xie-zhi-dinic EK 292ms #include <bits/std ...

  3. 洛谷P3376【模板】网络最大流 ISAP

    这篇博客写得非常好呀. 传送门 于是我是DCOI这一届第一个网络流写ISAP的人了,之后不用再被YKK她们嘲笑我用Dinic了!就是这样! 感觉ISAP是会比Dinic快,只分一次层,然后不能增广了再 ...

  4. [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码

    [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码 更坏的阅读体验 定义 对于给定的一个网络,有向图中每个的边权表示可以通过的最大流量.假设出发点S水流无限大,求水流到终点T后的最大流量. 起 ...

  5. 洛谷 P1546 最短网络 Agri-Net

    题目链接 https://www.luogu.org/problemnew/show/P1546 题目背景 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当 ...

  6. 洛谷P1546 最短网络 Agri-Net(最小生成树,Kruskal)

    洛谷P1546 最短网络 Agri-Net 最小生成树模板题. 直接使用 Kruskal 求解. 复杂度为 \(O(E\log E)\) . #include<stdio.h> #incl ...

  7. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  8. 『题解』洛谷P3376 【模板】网络最大流

    Problem Portal Portal1:Luogu Description 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. Input 第一行包含四个正整数\(N,M,S,T\),分 ...

  9. 洛谷 P3376 【模板】网络最大流 题解

    今天学了网络最大流,EK 和 Dinic 主要就是运用搜索求增广路,Dinic 相当于 EK 的优化,先用bfs求每个点的层数,再用dfs寻找并更新那条路径上的值. EK 算法 #include< ...

随机推荐

  1. 数据库常用sql语句积累

    组合一个新表 select p.*,(select value from as_info where key = 'v51_products') as v51_products from AP_POR ...

  2. 进入docker 容器内命令

    docker exec :在运行的容器中执行命令 语法 docker exec [OPTIONS] CONTAINER COMMAND [ARG...] OPTIONS说明: -d :分离模式: 在后 ...

  3. java实现随机数的生成

    一,课程中的动手动脑的问题 1,编写一个方法,使用以上算法生成指定数目的随机整数. public void suiJiShu(){ Scanner input=new Scanner(System.i ...

  4. [luogu] P3202 [HNOI2009]通往城堡之路(贪心)

    P3202 [HNOI2009]通往城堡之路 题目描述 听说公主被关押在城堡里,彭大侠下定决心:不管一路上有多少坎坷,不管城堡中的看守有多少厉害,不管救了公主之后公主会不会再被抓走,不管公主是否漂亮. ...

  5. ES6特性:(阮一峰老师)学习总结

    ES6(阮一峰)学习总结   1.块级作用域的引入 在ES6之前,js只有全局作用域和函数作用域,ES6中let关键字为其引入了块级作用域. { var a = 5; let b = 6; } con ...

  6. 数据库ifnull方法

    IFNULL(expr1,expr2)如果expr1不是NULL,IFNULL()返回expr1,否则它返回expr2.IFNULL()返回一个数字或字符串值.例如: ifnull() 如果sum(t ...

  7. Spring IoC简介及使用

    Spring根本任务 Spring的根本任务就是简化Java开发. 目前许多框架如果要使用他们,就必须要继承或实现这些框架的各种类.这使得框架与我们的程序耦合度过高.由于在我们的程序中加入了过多的框架 ...

  8. 创业笔记-Node.js入门之基于事件驱动的回调

    基于事件驱动的回调 这个问题可不好回答(至少对我来说),不过这是Node.js原生的工作方式.它是事件驱动的,这也是它为什么这么快的原因. 你也许会想花点时间读一下Felix Geisendörfer ...

  9. dubbo知识点理解

    1.分布式服务架构关键在于:用于提高业务复用及整合的 分布式服务框架(RPC) 是关键.注册中心是关键,提供业务复用和整合. 2.dubbo在消费方,获取服务列表后提供软负载均衡.dubbo在消费方提 ...

  10. iOS给label加入下划线

    UILabel *myLabel = [[UILabelalloc] ,, , )]; NSMutableAttributedString *content = [[NSMutableAttribut ...