DINIC网络流+当前弧优化

const
  inf=1000000000;
type
  rec=record
    s,e,w,next:longint;
  end;
var
  b,bb,d,q:array[-1..300001] of longint;
  a:array[-1..1000001] of rec;
  e:array[0..300001,1..3]of longint;
  n,m,i,j,k,l,st,ed,ww,top,ans,nn,dd,x:longint;
function min(aa,bb:longint):longint;
begin
  if aa<bb then exit(aa);exit(bb);
end;
procedure add(st,ed,ww:longint);
begin
  inc(top);
  a[top].s:=st;
  a[top].e:=ed;
  a[top].w:=ww;
  a[top].next:=b[st];
  b[st]:=top;
end;
function bfs:boolean;
var head,tail,x,u,i:longint;
  y:rec;
begin
  for i:=1 to n do d[i]:=-1;
  tail:=1; head:=0; d[st]:=0; q[1]:=st;
  while head<tail do
  begin
    inc(head); x:=q[head];
    u:=b[x];
    while u>0 do
    begin
      y:=a[u];
      if(d[y.e]=-1)and(y.w>0)then
      begin
        d[y.e]:=d[x]+1;
        inc(tail); q[tail]:=y.e;
      end;
      u:=y.next;
    end;
  end;
  if d[ed]=-1 then exit(false);
  exit(true);
end;
function addflow(p,maxflow:longint):longint;
var
  o,u:longint;
  y:rec;
begin
  if(p=ed)or(maxflow=0)then exit(maxflow);
  addflow:=0; u:=bb[p];
  while u>0 do
  begin
    y:=a[u];
    if(d[y.e]=d[p]+1)and(y.w>0)then
    begin
      o:=addflow(y.e,min(maxflow,y.w));
      if o>0 then
      begin
        dec(a[u].w,o); if a[u].w>0 then bb[p]:=u;
        inc(a[u xor 1].w,o);
        dec(maxflow,o); inc(addflow,o);
        if maxflow=0 then break;
      end;
    end;
    u:=y.next;
  end;
  if addflow=0 then d[p]:=-1;
end;
function network:longint;
var i:longint;
begin
  network:=0;
  while bfs do
  begin
    for i:=st to ed do bb[i]:=b[i];
    inc(network,addflow(st,inf));
  end;
end;
begin
  readln(n,m);
  top:=1; build;
  writeln(network);
end.
时间: 2024-12-26 09:54:56

DINIC网络流+当前弧优化的相关文章

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

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

最大流当前弧优化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 <

网络流之当前弧优化浅谈

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

模板 &#183; 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],

noip级别模板小复习

不是很noip的知识点就不写了. dij什么的太easy就不写了. 缩点 注意\(Tarjan\)在缩边双和求强联通分量时候的区别. 一个要判断是否在栈内一个不要. 最后\(topsort\)来\(dp\),或者记忆化搜索,但是一定要记得初值为\(-1\). 考虑图不联通. 负环 考虑图不联通. 一开始\(dis=0\),判断最短路长度大于\(n\)会好一些. \(dfs\)型\(spfa\)是指数级的. ST表 注意是\(i\)到\(i+2^k-1\). 所以预处理的时候不要减1,因为已经减过

[BZOJ1391]解题报告|网络流的又一类建图&amp;Dinic的若干优化

1391: [Ceoi2008]order 有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成. 现在给出这些参数,求最大利润 关于建图和思路 刚开始看这道题的时候十分纠结,任务的做与不做,应当是典型的最小割取舍模型 然而买机器和租机器,又是常见的最小费用最大流模型的标志 进一步思考,对于每一对如下关系(任务)-(机器) 一共有三种处理方法: 1)任务不做 2)租用机器 3)购买机器 好像看出了点眉目,对于第一种