算法模板——Dinic最小费用最大流
时间:2022-05-08
本文章向大家介绍算法模板——Dinic最小费用最大流,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
实现功能:输入M,N,S,T;接下来M行输入M条弧的信息(包括起点,终点,流量,单位费用);实现功能是求出以S为源点,T为汇点的网络最大流的最小费用
其实相当的像Dinic最大流呐= =
还是spfa处理出最短路径(注意,这次是最短路径,所以时空复杂度将有所提高,害得我都开循环队列了TT),然后顺着最短路径顺藤摸瓜找回去,求出流大小和最小的费用,然后,没有然后了,程序还是一样的好懂么么哒(HansBug:感觉Dinic算法真心超级喜感,为啥我之前就没发现呢= =,还有鸣谢wnjxyk神犇提供的C++模板么么哒 Wnjxyk:^_^)
(本程序为BZOJ1927的AC程序,模板题么么哒,还有其实感觉spfa函数里面每次清空e数组貌似不是很必要,但还是图个安心写下吧)
1 const maxl=100000;
2 type
3 point=^node;
4 node=record
5 g,w,f:longint;
6 next,anti:point;
7 end;
8 var
9 a,e:array[0..10000] of point;
10 i,j,k,l,m,n,s,t,ans,flow:longint;
11 c,g:array[0..10000] of longint;
12 d:array[0..maxl] of longint;
13 function min(x,y:longint):longint;
14 begin
15 if x<y then min:=x else min:=y;
16 end;
17 procedure swap(var x,y:longint);
18 var z:longint;
19 begin
20 z:=x;x:=y;y:=z;
21 end;
22 procedure add(x,y,z,t:longint);
23 var p:point;
24 begin
25 new(p);p^.g:=y;p^.w:=z;p^.f:=t;p^.next:=a[x];a[x]:=p;
26 new(p);p^.g:=x;p^.w:=0;p^.f:=-t;p^.next:=a[y];a[Y]:=p;
27 a[x]^.anti:=a[y];a[y]^.anti:=a[x];
28 end;
29 function spfa:boolean; //神(dou)奇(bi)的最短路径预处理
30 var f,r:longint;p:point;
31 begin
32 for i:=s to t do c[i]:=maxlongint;
33 for i:=s to t do e[i]:=nil;
34 d[1]:=s;f:=1;r:=2;g[s]:=1;c[s]:=0;
35 while f<>r do
36 begin
37 p:=a[d[f]];
38 while p<>nil do
39 begin
40 if (p^.w<>0) and (c[p^.g]>(c[d[f]]+p^.f)) then
41 begin
42 c[p^.g]:=c[d[f]]+p^.f;
43 e[p^.g]:=p;
44 if g[p^.g]=0 then
45 begin
46 g[p^.g]:=1;
47 d[r]:=p^.g;r:=(r mod maxl)+1;
48 end;
49 end;
50 p:=p^.next;
51 end;
52 g[d[f]]:=0;f:=(f mod maxl)+1;
53 end;
54 exit(c[t]<>maxlongint);
55 end;
56 procedure calc;
57 begin
58 l:=maxlongint;
59 i:=t;
60 while i<>s do
61 begin
62 l:=min(l,e[i]^.w);
63 i:=e[i]^.anti^.g; //当前弧的反向弧所指向的点就是你要回到的点^_^
64 end;
65 i:=t;inc(flow,l);
66 while i<>s do
67 begin
68 if e[i]^.w<>maxlongint then dec(e[i]^.w,l);
69 if e[i]^.anti^.w<>maxlongint then inc(e[i]^.anti^.w,l);
70 inc(ans,e[i]^.f*l);
71 i:=e[i]^.anti^.g;
72 end;
73 end;
74 begin
75 readln(n,m);s:=0;t:=2*n+1;
76 for s:=0 to t do a[i]:=nil;
77 for i:=1 to n do
78 begin
79 read(l);
80 add(0,i,1,0);
81 add(i+n,t,1,0);
82 add(0,i+n,1,l);
83 end;
84 readln;
85 for i:=1 to m do
86 begin
87 readln(j,k,l);
88 if j>k then swap(j,k);
89 add(j,k+n,1,l);
90 end;
91 flow:=0;ans:=0; //flow表示最大流;ans表示最小费用
92 while spfa do calc;
93 writeln(ans);
94 readln;
95 end.
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PHP实现文件上传操作和封装
- gearman中任务的优先级和返回状态实例分析
- php实现文件上传基本验证
- php加速缓存器opcache,apc,xcache,eAccelerator原理与配置方法实例分析
- php使用fputcsv实现大数据的导出操作详解
- php的无刷新操作实现方法分析
- PHP实现创建一个RPC服务操作示例
- php 下 html5 XHR2 + FormData + File API 上传文件操作实例分析
- gearman管理工具GearmanManager的安装与php使用方法示例
- php 的多进程操作实践案例分析
- php 输出缓冲 Output Control用法实例详解
- PHP使用gearman进行异步的邮件或短信发送操作详解
- php多进程并发编程防止出现僵尸进程的方法分析
- php+ajax实现文件切割上传功能示例
- php操作redis数据库常见方法实例总结