网络流——最大流Dinic算法
前言
突然发现到了新的一年什么东西好像就都不会了凉凉
算法步骤
- 建残量网络图
 - 在残量网络图上跑增广路
 - 重复1直到没有增广路(注意一个残量网络图要尽量把价值都用完,不然会浪费建图的时间)
 
代码实现
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define re register
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
inline int gi(){
    int f=1,sum=0;char ch=getchar();
    while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    return f*sum;
}
const int N=10010,M=100010,Inf=1e9+10;
int n,m,s,t,flow;
class Graph{
private:
    int front[N],nxt[M<<1],to[M<<1],w[M<<1],cnt,dep[N];
    bool bfs(){
        queue<int >Q;while(!Q.empty())Q.pop();
        memset(dep,0,sizeof(dep));
        Q.push(s);dep[s]=1;
        while(!Q.empty()){
            int u=Q.front();Q.pop();
            for(int i=front[u];i!=-1;i=nxt[i]){
                int v=to[i];
                if(!dep[v] && w[i]){
                    dep[v]=dep[u]+1;Q.push(v);
                }
            }
        }
        return dep[t];
    }
    int dfs(int u,int Flow){
        if(u==t || !Flow)return Flow;
        for(int i=front[u];i!=-1;i=nxt[i]){
            int v=to[i];
            if(dep[v]==dep[u]+1 && w[i]){
                int di=dfs(v,min(Flow,w[i]));
                if(di){
                    w[i]-=di;w[i^1]+=di;
                    return di;
                }
            }
        }
        return 0;
    }
public:
    void Add(int u,int v,int val){to[cnt]=v;nxt[cnt]=front[u];front[u]=cnt;w[cnt]=val;cnt++;}
    void init(){memset(front,-1,sizeof(front));cnt=0;}
    void Dinic(){
        while(bfs()){
            while(int d=dfs(s,Inf)){
                flow+=d;
            }
        }
    }
}MaxFlow;
int main(){
    n=gi();m=gi();s=gi();t=gi();
    MaxFlow.init();
    for(int i=1;i<=m;i++){
        int u=gi(),v=gi(),val=gi();
        MaxFlow.Add(u,v,val);MaxFlow.Add(v,u,0);
    }
    MaxFlow.Dinic();
    printf("%d\n",flow);
    return 0;
}
当前弧优化
考虑我们在dfs搜索的时候,是不是有什么东西重复了?
显然搜索过的就不可能再来了(因为已经被压榨干净了)
然后就可以修改一些dfs的过程。
int dfs(int u,int Flow){
    if(u==t || !Flow)return Flow;
    for(int &i=cur[u];i!=-1;i=nxt[i]){
        int v=to[i];
        if(dep[v]==dep[u]+1 && w[i]){
            int di=dfs(v,min(Flow,w[i]));
            if(di){
                w[i]-=di;w[i^1]+=di;
                return di;
            }
        }
    }
    return 0;
}
void Dinic(){
    while(bfs()){
        for(int i=1;i<=n;i++)cur[i]=front[i];
        while(int d=dfs(s,Inf)){
            flow+=d;
        }
    }
}
优化还是比较明显的。
大家可以在看完之后切了这道题目
当然陆续将会推出HLPP与ISAP的总结。
网络流——最大流Dinic算法的更多相关文章
- 网络流最大流——dinic算法
		
前言 网络流问题是一个很深奥的问题,对应也有许多很优秀的算法.但是本文只会讲述dinic算法 最近写了好多网络流的题目,想想看还是写一篇来总结一下网络流和dinic算法以免以后自己忘了... 网络流问 ...
 - [讲解]网络流最大流dinic算法
		
网络流最大流算法dinic ps:本文章不适合萌新,我写这个主要是为了复习一些细节,概念介绍比较模糊,建议多刷题去理解 例题:codevs草地排水,方格取数 [抒情一下] 虽然老师说这个多半不考,但是 ...
 - Power Network(网络流最大流 & dinic算法 + 优化)
		
Power Network Time Limit: 2000MS Memory Limit: 32768K Total Submissions: 24019 Accepted: 12540 D ...
 - 网络流之最大流Dinic算法模版
		
/* 网络流之最大流Dinic算法模版 */ #include <cstring> #include <cstdio> #include <queue> using ...
 - 网络流(最大流-Dinic算法)
		
摘自https://www.cnblogs.com/SYCstudio/p/7260613.html 网络流定义 在图论中,网络流(Network flow)是指在一个每条边都有容量(Capacity ...
 - 学习笔记 --- 最大流Dinic算法
		
为与机房各位神犇同步,学习下网络流,百度一下发现竟然那么多做法,最后在两种算法中抉择,分别是Dinic和ISAP算法,问过 CA爷后得知其实效率上无异,所以决定跟随Charge的步伐学习Dinic,所 ...
 - hdu-3572 Task Schedule---最大流判断满流+dinic算法
		
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3572 题目大意: 给N个任务,M台机器.每个任务有最早才能开始做的时间S,deadline E,和持 ...
 - 最大流——Dinic算法
		
前面花了很长时间弄明白了压入-重标记的各种方法,结果号称是O(V3)的算法测demo的时候居然TLE了一个点,看了题解发现所有人都是用Dinic算法写的,但它的复杂度O(V2E)明显高于前者,具体是怎 ...
 - 求最大流dinic算法模板
		
//最短增广路,Dinic算法 struct Edge { int from,to,cap,flow; };//弧度 void AddEdge(int from,int to,int cap) //增 ...
 
随机推荐
- ubuntu 安装jdk7小结(转载)
			
ubuntu 安装jdk7小结 目录(?)[+] ubuntu 安装jdk7,现在来总结一下:第一步:下载jdk-7-linux-i586.tar.gz直接在ORACLE的官网中下载就可以:http: ...
 - git学习笔记:一台电脑上配置两个git账户
			
如何在一台电脑上配置两个git账户,现在云端仓库很多,有开源中国的 gitee.com 微软的 github.com 还有 gitlab.com 和 bitbucket.org 等等,下面是具体步骤 ...
 - 如何在Eclipse下安装SVN插件——subclipse
			
如何在Eclipse下安装SVN插件——subclipse | 浏览:2799 | 更新:2014-09-20 22:39 1 2 3 4 5 6 分步阅读 版本控制是开发人员必不可少的工具,而SVN ...
 - mybatis不报错,但是查询结果为0
			
[转载]https://blog.csdn.net/shenzhenNBA/article/details/46673327 在用MyBatis操作数据库的时候相信很多人都用到,当在判断null, 大 ...
 - 关于ueditor   在struts2 中   上传图片  ,未找到上传文件  问题的解决方法
			
问题原因: ueditor 上传图片需请求imageUp.jsp文件,struts2 自带的拦截器(/*)把所有请求的文件都做了处理,所以导致无法上传图片. 解决方法: 方法一:自定义拦截器,让它在请 ...
 - LSTM长短期记忆神经网络模型简介
			
LSTM网络也是一种时间递归神经网络,解决RNN的长期依赖关系. RNN模型在训练时会遇到梯度消失或者爆炸的问题,训练时计算和反向传播,梯度倾向于在每一时刻递增或递减,梯度发散到无穷大或者0..... ...
 - TryXXX模式(深入理解c#)
			
.NET有几个模式很容易根据所涉及的方法名称来识别.例如,BeginXXX和EndXXX暗示着一个异步操作.TryXXX模式的用途在.net1.1升级到2.0期间进行了扩展.他是针对以下情况设计的:有 ...
 - 2018.11.01 NOIP训练 木棒分组(搜索+剪枝)
			
传送门 测试搜索的时候状态定义错了233. 我们把木棒从大到小排序. 然后保证每一组搜到的木棒出现的长度是从大到小递减的. 直接定义现在搜的木棒从什么位置开始,当前这一组的总长度,之前几组的总长度. ...
 - 牛客训练三:处女座和小姐姐(三)(数位dp)
			
题目链接:传送门 思路:数位dp的记忆化搜索模板 从高位向低位枚举,逐位确定每一位的6的个数,dp[i][s]表示处理到第i条边,状态为s时的数字的个数. 注意,要使用long long类型. #in ...
 - Codeforces Round #514 (Div. 2) E. Split the Tree(倍增+贪心)
			
https://codeforces.com/contest/1059/problem/E 题意 给出一棵树,每个点都有一个权值,要求你找出最少条链,保证每个点都属于一条链,而且每条链不超过L个点 和 ...