算法模板——sap网络最大流 3(递归+邻接表)

实现功能:同前

程序还是一如既往的优美,虽然比起邻接矩阵的稍稍长了那么些,不过没关系这是必然,但更重要的一个必然是——速度将是一个质的飞跃^_^(这里面的point指针稍作了些创新——anti指针,这个指向当前弧的反向弧,便于路径增广时的操作,相比非递归里面非要用一个op函数来挨个找已经强多了!!!)

 1 type
 2     point=^node;
 3     node=record
 4                g,w:longint;
 5                anti,next:point;
 6     end;
 7 var
 8    i,j,k,l,m,n,ans,s,t:longint;
 9    a:array[0..10000] of point;
10    d,dv:array[0..10000] of longint;
11 function min(x,y:longint):longint;inline;
12          begin
13               if x<y then min:=x else min:=y;
14          end;
15 procedure add(x,y,z:longint);inline;
16           var p:point;
17           begin
18                new(p);p^.g:=y;p^.w:=z;p^.next:=a[x];a[x]:=p;
19                new(p);p^.g:=x;p^.w:=0;p^.next:=a[y];a[y]:=p;
20                a[y]^.anti:=a[x];a[x]^.anti:=a[y];
21           end;
22 function dfs(x,flow:longint):longint;inline;
23          var i,j,k,l:longint;p:point;
24          begin
25               if x=t then exit(flow);
26               dfs:=0;p:=a[x];
27               while p<>nil do
28                     begin
29                          if (p^.w>0) and (d[x]=(d[p^.g]+1)) then
30                             begin
31                                  k:=dfs(p^.g,min(flow-dfs,p^.w));
32                                  dec(p^.w,k);
33                                  inc(p^.anti^.w,k);
34                                  inc(dfs,k);
35                                  if dfs=flow then exit;
36                             end;
37                          p:=p^.next;
38                     end;
39               if d[s]=n then exit;
40               dec(dv[d[x]]);
41               if dv[d[x]]=0 then d[s]:=n;
42               inc(d[x]);inc(dv[d[x]]);
43          end;
44 begin
45      readln(n,m,s,t);
46      for i:=1 to n do a[i]:=nil;
47      for i:=1 to m do
48          begin
49               readln(j,k,l);
50               add(j,k,l);
51          end;
52      fillchar(d,sizeof(d),0);
53      fillchar(dv,sizeof(dv),0);
54      dv[0]:=n;ans:=0;
55      while d[s]<n do inc(ans,dfs(s,maxlongint));
56      writeln(ans);
57 end.        
时间: 2024-10-10 06:46:23

算法模板——sap网络最大流 3(递归+邻接表)的相关文章

算法模板——sap网络最大流

实现功能:首行输入N,M,S,T,代表这张图N个点,M条边,源点为S,汇点为T:接下来T行输入个边的出发点.终点和权值:输出最大流 原理:sap网络流算法(详见百度百科,个人觉得这个模板已经不错了,虽然本人暂时还未考虑引入邻接表进行优化) 1 var 2 i,j,k,l,m,n,ans,aug,s,t,tmp,jl,mi:longint; 3 flag:boolean; 4 vh,dis,di,his,pre:array[0..10000] of longint; 5 map:array[0..

算法模板——sap网络最大流 2

实现功能:同最大流 1 这里面主要是把前面的邻接矩阵改成了邻接表,相比之下速度大大提高——本人实测,当M=1000000 N=10000 时,暂且不考虑邻接矩阵会不会MLE,新的程序速度快了很多倍(我们家这个很弱的电脑上耗时0.3s):而当M=300000 N=10000时,优势更加明显(几乎是秒出),别的没了,尤其当遇到稀疏图的时候这样子是大大划算的!!! 1 type 2 point=^node; 3 node=record 4 g,w:longint; 5 next:point; 6 en

算法模板——sap网络最大流 3(递归+邻接矩阵)

实现功能:同之前 可以看见的是这次的程序优美了许多,代码简短了一倍还多,可是速度却是和原来的邻接表一个级别的(在Codevs上面草地排水那题的运行时间比较,但是显然数据很大时应该比那个慢些),原理差不多,感觉dfs里面的来回倒变量很神奇 1 var 2 s,t,i,j,k,l,m,n,ans:longint; 3 a:array[0..1000,0..1000] of longint; 4 d,dv:array[0..10000] of longint; 5 function min(x,y:l

算法模板——Dinic网络最大流 2

实现功能:同Dinic网络最大流 1 这个新的想法源于Dinic费用流算法... 在费用流算法里面,每次处理一条最短路,是通过spfa的过程中就记录下来,然后顺藤摸瓜处理一路 于是在这个里面我的最大流也采用这种模式,这样子有效避免的递归,防止了爆栈么么哒 1 type 2 point=^node; 3 node=record 4 g,w:longint; 5 next,anti:point; 6 end; 7 var 8 i,j,k,l,m,n,s,t,flow:longint; 9 a,e:a

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

P3376 [模板]网络最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行包含三个正整数ui.vi.wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi) 输出格式: 一行,包含一个正整数,即为该网络的最大流. 输入输出样例 输入样例#1: 复制 4 5 4 3 4 2 30 4 3 20 2 3 20 2 1 30

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

题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行包含三个正整数ui.vi.wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi) 输出 一行,包含一个正整数,即为该网络的最大流. 样例输入 4 5 4 3 4 2 30 4 3 20 2 3 20 2 1 30 1 3 40 样例输出 50 数据规模: 对于30%的数据:N<=10,M<=2

luogu P3376 【模板】网络最大流

题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行包含三个正整数ui.vi.wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi) 输出格式: 一行,包含一个正整数,即为该网络的最大流. 输入输出样例 输入样例#1: 4 5 4 3 4 2 30 4 3 20 2 3 20 2 1 30 1 3 40 输出样例#1: 50

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

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problemnew/show/3376 题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行包含三个正整数ui.vi.wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi) 输出格式: 一行,包含一个正

P3376 【模板】网络最大流(70)

题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行包含三个正整数ui.vi.wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi) 输出格式: 一行,包含一个正整数,即为该网络的最大流. 输入输出样例 输入样例#1: 4 5 4 3 4 2 30 4 3 20 2 3 20 2 1 30 1 3 40 输出样例#1: 50