【精选】最大流与最小费用流.pdfVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
【精选】最大流与最小费用流

最大流与最小费用流 前两个星期都在看最大流与费用流,在找标程时几乎所有的都是 C++的,少数几个 Pascal 的,要么代码风格乱七八糟,要么是不含任何优化的,我照着其中一个写下来最后 发现居然是错的!最后请教了 cyx 并摸索了他的C++代码,终于“修成正果”。把自己的心 得贴在这里,给那些跟我一样看不懂 C 的在最大流与费用流中探索的 OIers 一点小小的 help,顺便给自己攒点人品(或许我该去转C 了,毕竟要跟得上时代)。 最大流我写的是Dinic 算法,因为找不到传说中特别高效的SAP,所以就将就一下。事 实上我写了几道最大流的题目,发现Dinic 效率还是不错的,而且编程复杂度又低,在OI 中还是蛮实用的。 算法思想就是建立残留网络,每次找到在残留网络中的一条增广路进行增广,添加反向 边的目的就是用来退流的(想想为什么?)。而Dinic 在这基础上进行改进,就是构建层次 图,沿层次图进行多路增广(不懂的话详细看代码)。 程序如下: program maxflow; var E,w,pre:array[0..20000] of longint; pot,dist,q:array[0..10000] of longint; n,m,s,t,ans,L:longint; procedure add(a,b,c:longint); //用链式前向星存储 begin E[L]:=b; //E 数组存点 w[L]:=c; //w 数组存每条边的容量 pre[L]:=pot[a]; //pre 数组记录起点同样为a 的前一条边 pot[a]:=L; //pot 数组为索引表 inc(L) //数组要从 0 开始存,否则后面的xor 会出错,我因这个调了2 小时 end; procedure init; //直接建立残留网络,不用存原图 var i,a,b,c:longint; begin L:=0; fillchar(pre,sizeof(pre),255); //这两个数组要初始化为-1,与后面调用 fillchar(pot,sizeof(pot),255); 对应 readln(n,m); for i:=1 to m do begin readln(a,b,c); add(a,b,c); //在残留网络中添加一条a 到b 剩余容量为c 的边 add(b,a,0) //添加反向边 end; s:=1; t:=n //s 为源,t 为汇 end; function bfs:boolean; //宽搜进行构建层次图(到源点的最短距离), var k,head,tail:longint; 因为每条边在这的距离权值都一样(为 1 ), begin 所以不用写成spfa,cyx 所教Orz fillchar(q,sizeof(q),0); fillchar(dist,sizeof(dist),255); //初始化为-1,用于退出时的判定 head:=1; tail:=2; q[head]:=s; dist[s]:=0; while headtail do //不需要采用循环队列,显然每个点只入队一次 begin k:=pot[q[head]]; while k-1 do begin if (w[k]0) and (dist[E[k]]=-1) then begin dist[E[k]]:=dist[q[head]]+1; q[tail]:=E[k]; inc(tail) end; k:=pre[k] end; inc(head) end; if dist[t]-1 then exit(true) //是否存在增广路 else exit(false) end; function min(a,b:longint):longint; begin if ab then min:=b else min:=a end; functi

文档评论(0)

pfenejiarz + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档