算法模板——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     end;
  7
  8 var
  9    i,j,k,l,m,n,tmp,ans,aug,mi,s,t:longint;
 10    di,a:array[0..10005] of point;
 11    pre,his,dis,vh:array[0..10005] of longint;
 12    flag:boolean;p,jl:point;
 13 function min(x,y:longint):longint;inline;
 14          begin
 15               if x<y then  min:=x else min:=y;
 16          end;
 17 function add(x,y,z:longint):longint;inline;
 18           var p:point;
 19           begin
 20                new(p);p^.w:=z;p^.g:=y;
 21                p^.next:=a[x];a[x]:=p;
 22           end;
 23 procedure op(x,y,z:longint);inline;
 24           var p:point;
 25           begin
 26                p:=a[x];
 27                while p<>nil do
 28                      begin
 29                           if (p^.g=y) and ((p^.w+z)>=0) then
 30                              begin
 31                                   p^.w:=p^.w+z;
 32                                   break;
 33                              end;
 34                           p:=p^.next;
 35                      end;
 36           end;
 37 begin
 38      readln(n,m,s,t);
 39      for i:=1 to n do a[i]:=nil;
 40      for i:=1 to m do
 41          begin
 42               readln(j,k,l);
 43               add(j,k,l);add(k,j,0);
 44          end;
 45      for i:=1 to n do di[i]:=a[i];
 46      fillchar(dis,sizeof(dis),0);
 47      fillchar(pre,sizeof(pre),0);
 48      fillchar(his,sizeof(his),0);
 49      fillchar(vh,sizeof(vh),0);
 50      i:=s;vh[0]:=n;ans:=0;aug:=maxlongint;
 51      while dis[s]<n do
 52            begin
 53                 flag:=false;his[i]:=aug;
 54                 p:=a[i];
 55                 while p<>nil do
 56                       begin
 57                            if (p^.w>0) and (dis[i]=(dis[p^.g]+1)) then
 58                               begin
 59                                    aug:=min(aug,p^.w);
 60                                    pre[p^.g]:=i;di[i]:=p;
 61                                    flag:=true;i:=p^.g;
 62                                    if i=t then
 63                                       begin
 64                                            ans:=ans+aug;
 65                                            while i<>s do
 66                                                  begin
 67                                                       tmp:=i;
 68                                                       i:=pre[i];
 69                                                       op(i,tmp,-aug);
 70                                                       op(tmp,i,aug);
 71                                                  end;
 72                                            aug:=maxlongint;
 73                                       end;
 74                                    break;
 75                               end;
 76                            p:=p^.next;
 77                       end;
 78                 if flag then continue;
 79                 jl:=nil;mi:=n-1;
 80                 p:=a[i];
 81                 while p<>nil do
 82                       begin
 83                            if (p^.w>0) and (dis[p^.g]<mi) then
 84                               begin
 85                                    jl:=p;mi:=dis[p^.g];
 86                               end;
 87                            p:=p^.next;
 88                       end;
 89                 di[i]:=jl;
 90                 dec(vh[dis[i]]);
 91                 if vh[dis[i]]=0 then break;
 92                 dis[i]:=mi+1;
 93                 inc(vh[dis[i]]);
 94                 if i<>s then
 95                    begin
 96                         i:=pre[i];
 97                         aug:=his[i];
 98                    end;
 99            end;
100      writeln(ans);
101 end.
102                 
时间: 2024-10-02 19:13:11

算法模板——sap网络最大流 2的相关文章

算法模板——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网络最大流 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,a

算法模板——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