题解 洛谷 P3376 【【模板】网络最大流】
本人很弱,只会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 【【模板】网络最大流】的更多相关文章
- 【最大流ISAP】洛谷P3376模板题
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...
- P3376 [模板] 网络最大流
https://www.luogu.org/blog/ONE-PIECE/wang-lao-liu-jiang-xie-zhi-dinic EK 292ms #include <bits/std ...
- 洛谷P3376【模板】网络最大流 ISAP
这篇博客写得非常好呀. 传送门 于是我是DCOI这一届第一个网络流写ISAP的人了,之后不用再被YKK她们嘲笑我用Dinic了!就是这样! 感觉ISAP是会比Dinic快,只分一次层,然后不能增广了再 ...
- [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码
[洛谷P3376题解]网络流(最大流)的实现算法讲解与代码 更坏的阅读体验 定义 对于给定的一个网络,有向图中每个的边权表示可以通过的最大流量.假设出发点S水流无限大,求水流到终点T后的最大流量. 起 ...
- 洛谷 P1546 最短网络 Agri-Net
题目链接 https://www.luogu.org/problemnew/show/P1546 题目背景 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当 ...
- 洛谷P1546 最短网络 Agri-Net(最小生成树,Kruskal)
洛谷P1546 最短网络 Agri-Net 最小生成树模板题. 直接使用 Kruskal 求解. 复杂度为 \(O(E\log E)\) . #include<stdio.h> #incl ...
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- 『题解』洛谷P3376 【模板】网络最大流
Problem Portal Portal1:Luogu Description 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. Input 第一行包含四个正整数\(N,M,S,T\),分 ...
- 洛谷 P3376 【模板】网络最大流 题解
今天学了网络最大流,EK 和 Dinic 主要就是运用搜索求增广路,Dinic 相当于 EK 的优化,先用bfs求每个点的层数,再用dfs寻找并更新那条路径上的值. EK 算法 #include< ...
随机推荐
- 7、A Design of Group Recommendation Mechanism Considering Opportunity Cost and Personal Activity Using Spark Framework---使用Spark框架的基于机会成本以及个人活动群组推荐机制
来源EDB2018---EDB 一.摘要: 组推荐是将一种项目(例如产品.服务)推荐给由多个成员组成的组的方法. 最小痛苦法(least Misery)是一种具有代表性的群体推荐方法,其能够推荐考虑群 ...
- BZOJ 2806 [Ctsc2012]Cheat (后缀自动机+二分+单调队列+dp)
题目大意: 给你一堆模式串和文本串 对于每个文本串,我们可以把它不可重叠地拆分成很多子串,如果拆分出的串作为子串出现在了任何一个模式串中,我们称它是“眼熟的”,我们必须保证“眼熟的”子串总长度不小于文 ...
- python的基础及练习
1.变量变是指变化,量是指反映某种状态例:level =1 或 2 username = ‘xuanxuan’password = ‘123’python里的“=”是赋值的意思,并不是真的等于 变量有 ...
- input只能输入数字或两位小数
/** * [只能输入数字和两位小数] * 举例:<input type="text" onkeyup="num(this)" size="10 ...
- hadoop中HDFS文件系统 nameNode出现的问题 nameNode无法打开
1,修改core-site.xml文件,先改成localhost,将所有进程关闭stop-all.sh(或者是先关闭所有进程,然后再修改文件),然后重启,在修改core-site.xml文件成ip地址 ...
- MATLAB解析PFM格式图像
http://www.p-chao.com/ja/2016-09-27/matlab%E8%A7%A3%E6%9E%90pfm%E6%A0%BC%E5%BC%8F%E5%9B%BE%E5%83%8F/ ...
- Javascript的jsonp原理
Javascript的jsonp原理 首先JSON是一种基于文本的数据交换方式,或者叫做数据描述格式 当一个网页在请求JavaScript文件时则不受是否跨域的影响,凡是拥有”src”这个属性的标 ...
- [terry笔记]学校管理系统
如下是要求: # 角色:学校.学员.课程.讲师# 要求:# 1. 创建北京.上海 2 所学校# 2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上 ...
- linux内核(三)文件系统
1.为什么需要根文件系统 (1)init进程的应用程序在根文件系统上(2)根文件系统提供了根目录/(3)内核启动后的应用层配置(etc目录)在根文件系统上.几乎可以认为:发行版=内核+rootfs(4 ...
- NYIST 1030 Yougth's Game[Ⅲ]
Yougth's Game[Ⅲ]时间限制:3000 ms | 内存限制:65535 KB难度:4 描述有一个长度为n的整数序列,A和B轮流取数,A先取,每次可以从左端或者右端取一个数,所有数都被取完时 ...