模板 · ISAP网络流+GAP优化+弧优化

//ISAP+GAP优化+弧优化
#include <bits/stdc++.h>
#define H cout<<"HYX"<<endl;
using namespace std;
const int INF = 0x7f7f7f7f;
struct Edge{int from, to, f;};

int n, m, s, t, ct=1;
int Hed[10005], Nex[2*100005], Cur[10005], Dep[10005], Num[10005], Pre[10005];
Edge E[2*100005];

void Add(int &a, int &b, int &f){
    E[++ct].from=a, E[ct].to=b, E[ct].f=f, Nex[ct]=Hed[a], Hed[a]=ct;
    E[++ct].from=b, E[ct].to=a, E[ct].f=0, Nex[ct]=Hed[b], Hed[b]=ct;
}
void BFS(){
    queue<int> Q;
    memset(Dep, 0, sizeof Dep);
    Dep[t] = 1;  Q.push(t);
    int k;
    while(!Q.empty()){
        k = Q.front(); Q.pop();
        Num[Dep[k]]++;
        for(int i=Hed[k]; i; i=Nex[i]){
            if(E[i^1].f && !Dep[E[i].to]){
                Dep[E[i].to] = Dep[k]+1;
                Q.push(E[i].to);
            }
        }
    }
}
int Agument(){
    int k = t, flow = INF;
    while(k != s){
        if(E[Pre[k]].f < flow) flow = E[Pre[k]].f;
        k = E[Pre[k]].from;
    }
    k = t;
    while(k != s){
        E[Pre[k]].f -= flow;
        E[Pre[k]^1].f += flow;
        k = E[Pre[k]].from;
    }
    return flow;
}
int ISAP(int maxdep){
    int flow = 0, k = s, mindep;
    BFS();
    memcpy(Cur, Hed, sizeof Hed);
    bool can;
    while(Dep[s] <= maxdep){
        if(k == t){
            flow += Agument();
            k = s;
        }
        can = 0;
        for(int i=Cur[k]; i; i=Nex[i]){
            if(E[i].f && Dep[E[i].to]+1==Dep[k]){
                can = 1;
                Pre[E[i].to] = i;
                Cur[k] = i;
                k = E[i].to;
                break;
            }
        }
        if(!can){
            mindep = n+1;
            for(int i=Hed[k]; i; i=Nex[i])
                if(Dep[E[i].to]<mindep && E[i].f)
                    mindep = Dep[E[i].to];

            if(!--Num[Dep[k]]) break;
            Num[Dep[k]=mindep+1]++;
            Cur[k] = Hed[k];
            if(k != s) k = E[Pre[k]].from;
        }
    }
    return flow;
}
int main(){
    scanf("%d%d%d%d", &n, &m, &s, &t);
    int u, v, c;
    for(int i=1; i<=m; ++i){
        scanf("%d%d%d", &u, &v, &c);
        Add(u, v, c);
    }
    printf("%d", ISAP(n));
    return 0;
}

原文地址:https://www.cnblogs.com/bosswnx/p/10353301.html

时间: 2024-10-11 05:47:06

模板 · ISAP网络流+GAP优化+弧优化的相关文章

P3376 网络流-最大流模板题(Dinic+当前弧优化)

(点击此处查看原题) Dinic算法 Dinic算法相对于EK算法,主要区别在于Dinic算法对图实现了分层,使得我们可以用一次bfs,一次dfs使得多条增广路得到增广 普通的Dinic算法已经可以处理绝大多数最大流(最小割)的题目了,但是总是有些题目会卡住普通的Dinic算法,此时我们就需要用到当前弧优化了 当前弧优化简述 不要小看当前弧优化,这个优化效果可是很明显的,就这个例题来说,我用普通的Dinic算法用时约1.7s,而使用了当前弧优化的Dinic算法后,只用了176ms,由此可以看出这

网络流之当前弧优化浅谈

在dinic中,我们会发现,dfs中每条边都会遍历至少一遍,那么我们可以把一定不会用到的边删去吗? 答案是当然可以,这就用到了当前弧优化: 其实这个优化在很久很久以前学习欧拉回路的时候就接触到了: 每次增广一条路后可以看做“榨干”了这条路,既然榨干了就没有再增广的可能了.但如果每次都扫描这些“枯萎的”边是很浪费时间的.那我们就记录一下“榨取”到那条边了,然后下一次直接从这条边开始增广,就可以节省大量的时间.这就是 当前弧优化 . 实现方法就是每次dfs时将head数组复制一遍,然后再新数组中跑d

最大流当前弧优化Dinic分层模板

最大流模板: 普通最大流 无向图限制:将无向图的边拆成2条方向相反的边 顶点有流量限制:拆成2个点,连接一条容量为点容量限制的边 无源汇点有最小流限制的最大流:理解为水管流量形成循环,每根水管有流量限制,并且流入量等于流出量 有源汇点的最小流限制的最大流 有最小流量限制的最小流 容量为负数:不能直接利用最大流求边权为负数的最小割.不知道怎么具体处理... 模板使用Dinic分层算法,使用了当前弧优化,效率还是不错的,使用的是vector存图,如果使用邻接表存图效率应该会高一些些吧. 但是ispa

Dinic + 当前弧优化 模板及教程

在阅读本文前,建议先自学最大流的Ek算法. 引入 Ek的核心是执行bfs,一旦找到增广路就停下来进行增广.换言之,执行一遍BFS执行一遍DFS,这使得效率大大降低.于是我们可以考虑优化. 核心思路 在一次BFS中,找到的增广路可能不止一条,这时我们可以本着"尽量少进行BFS"的想法,在一次bfs后把所有能增广的路径全部增广. 具体怎么做呢? 仍然是: while(bfs(源点,汇点)) dfs(): 每次bfs标记出每个点的"深度",也就是距离源点的长度.我们将得到

Dinic当前弧优化 模板及教程

在阅读本文前,建议先自学最大流的Ek算法. 引入 Ek的核心是执行bfs,一旦找到增广路就停下来进行增广.换言之,执行一遍BFS执行一遍DFS,这使得效率大大降低.于是我们可以考虑优化. 核心思路 在一次BFS中,找到的增广路可能不止一条,这时我们可以本着“尽量少进行BFS”的想法,在一次bfs后把所有能增广的路径全部增广.具体怎么做呢?仍然是:while(bfs(源点,汇点)) dfs(): 每次bfs标记出每个点的“深度”,也就是距离源点的长度.我们将得到的新图称作分层图.接下来我们在分层图

P3355 骑士共存问题 二分建图 + 当前弧优化dinic

P3355 骑士共存问题 题意: 也是一个棋盘,规则是“马”不能相互打到. 思路: 奇偶点分开,二分图建图,这道题要注意每个点可以跑八个方向,两边都可以跑,所以边 = 20 * n * n. 然后dinic 要用当前弧优化. #include <algorithm> #include <iterator> #include <iostream> #include <cstring> #include <cstdlib> #include <

性能优化——算法优化

背景 由于某种原因,我们系统需要记录另一个系统中一个表里的id.但是,当我们记录完了以后,别人系统可能会删除那个表里的一些数据,这样的话,我们这边就多了一些无效数据,所以,我们必须的找到这些无效的id,然后将其删除. 开始,我们的实现是这样:我们将记录下来的所有id放在一个list里,然后传到另一个系统,他将他们已经删除的id返回.具体处理代码如下: <pre name="code" class="java">public String findDele

凸优化之优化、对偶、KKT-七月算法(julyedu.com)4 月机器学习算法班学习笔记

优化 一般优化问题的基本形式 凸优化的基本形式 共轭函数 共轭函数是凸函数 对偶问题 拉格朗日函数 拉格朗日对偶函数 KKT条件 小结 优化 一般优化问题的基本形式 minimizef0(x),x∈Rn s.t.fi(x)≤0,i=1?m s.t.hj(x)=0,j=1?n 定义域为 当 m=n=0 时,约束优化问题退化成无约束优化问题 注意:这是是优化问题的一般形式,对 fi(x) 和 hi(x) 无特殊要求.就是并不要求这些函数一定可导,也不要求只有一个极值点,就是啥要求都没. 凸优化的基本

优化!优化!

网上看到一篇文章,虽然它讲的是一个js库内部的方法,但对我理解js的MVC模式还是很有帮助的,为防止以后访问不了,先抄下来: $.Class为javascript模拟了继承的实现,他将jquery面向函数的编程和面向对象的编程衔接在一起.$.Class基于 John Resig 的Simple Class类库,除了原型继承外,他还有其他一些特性:静态继承.自描述(Introspection).命名空间的支持.创建和初始化方法.更容易创建的回调函数. 构造函数 我们通过下面的方式生命一个类型: $