网络流之最大流问题

Reference:

http://blog.csdn.net/rrerre/article/details/6751520

http://blog.csdn.net/y990041769/article/details/21026445

http://www.nocow.cn/index.php/Translate:USACO/NetworkFlow

 

最大流Edmonds_Karp算法模板:

EK算法即增广路算法。

最大流最小割定理:最大流等于最小割

见白书P210

 

算法思想:

step 1. 令所有弧的流量为0,从而构造一个流量为0的可行流f(称作零流)。
step 2. 若f中找不到可改进路则转step 5;否则找到任意一条可改进路P。
step 3. 根据P求delta。
step 4. 以delta为改进量,更新可行流f。转step 2。
step 5. 算法结束。此时的f即为最大流。

算法的关键步骤是step 2,即:判断是否存在可改进路,若存在又如何求。
可以考虑用广度优先搜索。设置标志数组,记录顶点是不是被访问过;使用队列来存储已经访问过的顶点;另用一个一维数组p[i],记录每个顶点是由哪个顶点扩展而来(即记录父亲节点)。
首先S入队列。然后每次取队首顶点v,分析所有与v相邻的未访问顶点u:
1、存在弧<v, u>(正向弧),且u未访问。若f(v,u)<C(v,u)(非饱和弧),那么u入队列,给u打上“已访问”的标志,记u的父亲节点为v。
2、存在弧<u, v>(反向弧),且u未访问。若f(u,v) > 0(非零流弧),那么u入队列,给u打上“已访问”的标志,记u的父亲节点为-v。(以示和正向弧的区别)。
扩展完成后,若T还没有被访问就必然不存在可改进路;否则就从T出发,根据记录好的每个顶点的父亲节点信息,顺藤摸瓜,找出可改进路(同时还可以计算出delta)。

 

起点st,终点m

#include <iostream>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
int n,m,st,en;
int cap[300][300];    //cap[u][v]:边(u,v)上的最大流量
int flow[300][300];    //flow[u][v]:边(u,v)上当前的流量
int a[300];        //a[u]:访问标记,同时还记录下delta值
int p[300];        //记录父节点用
const int inf=100000000;int EK()            //st-->m
{queue<int> Q;memset(flow,0,sizeof(flow));memset(p,-1,sizeof(p));int f=0,minflow=inf;while(1){memset(a,0,sizeof(a));a[st]=inf;          Q.push(st);         while(!Q.empty()){int u=Q.front();Q.pop();for(int v=1;v<=m;v++)if(!a[v]&&cap[u][v]>flow[u][v]){p[v]=u;Q.push(v);a[v]=a[u]<cap[u][v]-flow[u][v]?a[u]:cap[u][v]-flow[u][v];}}if(a[m]==0) break;for (int u=m;u!=st;u=p[u])          {flow[p[u]][u]+=a[m];flow[u][p[u]]-=a[m];}f+=a[m];}return f;
}int main()
{int S,E,C;while (cin>>n>>st>>m)       //st->m
    {memset(cap,0,sizeof(cap));for (int i=1;i<=n;i++){cin>>S>>E>>C;cap[S][E]+=C;    //处理重边。有些题目,一条路上先给了容量30,然后重复了一次50,这时候这条路上的容量应该是30+50。
        }cout<<EK()<<endl;}return 0;
}
View Code

 

模板例题:

hdu1532

 

补充:需要拆点的问题:POJ3281

http://www.2cto.com/kf/201210/164289.html

http://moxi466839201.blog.163.com/blog/static/18003841620112316351118/

 

-------------------------------------------------------------------------------------------

补充个ISAP模板,比EK算法快,但是难想难写。看不懂T^T...

#include <iostream>
#include <cstdio>
#include <climits>
#include <cstring>
#include <algorithm>
using namespace std;
typedef  struct {int v,next,val;} edge;
const int MAXN=20010;
const int MAXM=500010;
edge e[MAXM];
int p[MAXN],eid;
void init(){memset(p,-1,sizeof(p));eid=0;}
void insert1(int from,int to,int val) //有向
{e[eid].v=to;e[eid].val=val;e[eid].next=p[from];p[from]=eid++;swap(from,to);e[eid].v=to;e[eid].val=0;e[eid].next=p[from];p[from]=eid++;
}
void insert2(int from,int to,int val) //无向
{e[eid].v=to;e[eid].val=val;e[eid].next=p[from];p[from]=eid++;swap(from,to);e[eid].v=to;e[eid].val=val;e[eid].next=p[from];p[from]=eid++;
}
int n,m;//n为点数 m为边数
int h[MAXN];
int gap[MAXN];
int s,t;
int dfs(int pos,int cost)
{if (pos==t) return cost;int j,minh=n-1,lv=cost,d;for (j=p[pos];j!=-1;j=e[j].next){int v=e[j].v,val=e[j].val;if(val>0){if (h[v]+1==h[pos]){if (lv<e[j].val) d=lv;else d=e[j].val;d=dfs(v,d);e[j].val-=d;e[j^1].val+=d;lv-=d;if (h[s]>=n) return cost-lv;if (lv==0) break;}if (h[v]<minh)    minh=h[v];}}if (lv==cost){--gap[h[pos]];if (gap[h[pos]]==0) h[s]=n;h[pos]=minh+1;++gap[h[pos]];}return cost-lv;
}
int isap(int st,int ed)
{s=st;t=ed;int ret=0;memset(gap,0,sizeof(gap));memset(h,0,sizeof(h));gap[st]=n;while (h[st]<n)ret+=dfs(st,INT_MAX);return ret;
}
int main()
{while(cin>>m>>n){init();for(int i=0;i<m;i++){int u,v,c;scanf("%d%d%d",&u,&v,&c);insert1(u,v,c);}printf("%d\n",isap(1,n));}return 0;
}
View Code

 

补充:sap、isap(sap+gap优化)、dinic算法:

http://blog.csdn.net/sprintfwater/article/details/7913181

sap算法:

http://www.cnblogs.com/longdouhzt/archive/2011/09/04/2166187.html

转载于:https://www.cnblogs.com/pdev/p/3873789.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/273643.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浅谈 trie树 及其实现

定义&#xff1a;又称字典树&#xff0c;单词查找树或者前缀树&#xff0c;是一种用于快速检索的多叉树结构&#xff0c; 如英文字母的字典树是一个26叉树&#xff0c;数字的字典树是一个10叉树。 核心思想&#xff1a;是空间换时间.利用字符串的公共前缀来降低查询时间的开销以…

Docker-compose 安装与基本使用(四)

安装 Docker-Compose Compose有多种安装方式,例如通过 shell, pip以及将 Compose作为容器安装等。本次安装以Shell 为主。 通过以下命令自动下载并安装适应系统版本的 Compose: curl -L "https://github.com/docker/compose/releases/download/1.10.0/docker-compose-$(un…

git pull 报错:Untracked Fles Preventing Merge

场景 使用 git pull 命令更新报错解决 找到对应的文件删除后重新打开项目。

SpringBoot 配置多数据源

项目Git地址&#xff1a;SpringBoot 配置多数据源&#xff1a;Jacob-multi-data-source 准备工作 准备两个数据库(此模块中两个数据库一个为本地 一个为远程&#xff0c;本地为主&#xff0c;远程为从)。然后建表。 #本地库 CREATE TABLE username (id bigint(11) NOT NULL AUT…

微服务之基础知识

什么是微服务架构 微服务是系统架构上的一种设计风格&#xff0c; 它的主旨是将一个原本独立的系统拆分成多个小型服务&#xff0c;这些小型服务都在各自独立的进程中运行&#xff0c;服务之间通过基于HTTP的RESTful API进行通信协作。 被拆分成的每一个小型服务都围绕着系统中…

还是俄罗斯方块之android版

前面的&#xff0c;口水话 请直接跳过。 虽然现在不比以前了 也没多少人气了&#xff0c;放到首页 都不到几百的点击量。也许博客园整体水平也是在往水的方向发展。不谈那些了&#xff0c;哥也曾经辉煌过 有过一天上千的点击量 &#xff0c;哥也曾经有过粉丝&#xff0c;被小妹…

自定义快捷命令程序(VC++加批处理)

一 概述 在看《从小工到专家-程序员修炼之道》时&#xff0c;看到建议使用Shell&#xff0c;很有感触。在很多时候&#xff0c;通过键盘操作&#xff0c;比鼠标的确会块很多&#xff0c;如果能用好shell命令&#xff08;或批处理命令&#xff09; &#xff0c;的确能节省我们…

7. Adapter

转载于:https://www.cnblogs.com/anit/p/3930202.html

jQuery 学习笔记(jQuery: The Return Flight)

第一课. ajax&#xff1a;$.ajax(url[, settings]) 练习代码&#xff1a; $(document).ready(function() {$("#tour").on("click", "button", function() {$.ajax(/photos.html, {success: function(response) {$(.photos).html(response).fadeI…

于我,过去,现在和未来 —— 西格里夫·萨松

In me, past, present, future meet            于我&#xff0c;过去、现在和未来To hold long chiding conference              商讨聚会 各执一词 纷扰不息My lusts usurp the present tense             林林总总的 欲望&#xff0c;…

Java assert关键字

Java assert关键字 Assert 简介 Java2在1.4中新增了一个关键字&#xff1a;assert。在程序开发过程中使用它创建一个断言(assertion)。语法格式有两种&#xff1a; assert condition; 这里condition是一个必须为真(true)的表达式。如果表达式的结果为true&#xff0c;那么断言为…

计算几何 半平面交

LA 4992 && hdu 3761 Jungle Outpost 杭电的有点坑啊。。一直爆内存&#xff0c;后来发现大白的半平面交模板那里 point *p new point[n]; line *q new line[n]这里出了问题&#xff0c;应该是在函数里面申请不了比较大的数组&#xff0c;所以爆内存。。我在全局定义…

Maven 强制导入jar包

场景 有时候因为各种原因(依赖有了&#xff0c;jar包有了)&#xff0c;项目中就是没有这个jar包。 在需要强导的项目中创建lib文件夹&#xff0c;将需要强导的jar包访问lib中。添加依赖$&#xff5b;pom.basedir&#xff5d;:获取当前所在的项目目录 $&#xff5b;pom.basedir&…

《Java 高并发》03 线程的生命周期

相关概念 进程是指一个内存中运行的应用程序&#xff0c;每个进程都有自己独立的一块内存空间&#xff0c;一个进程中可以启动多个线程。 一个进程是一个独立的运行环境&#xff0c;它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一个包含…

Spring boot 整合dynamic实现多数据源

项目git地址&#xff1a;Jacob-dynamic 准备工作 # 创建数据库db1 CREATE DATABASE db1CHARACTER SET utf8 COLLATE utf8_bin # 创建user表 CREATE TABLE user (id int(11) DEFAULT NULL,name varchar(255) DEFAULT NULL ) ENGINEInnoDB DEFAULT CHARSETutf8 # 添加数据 INSERT…

Could not autowire. No beans of 'JavaMailSender' type found..md

Could not autowire. No beans of JavaMailSender type found. 导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId><version>2.1.5.RELEASE</version> </depe…

极客Web前端开发资源集锦

本周我们带来的前端推荐包含当前热门的bootstrap&#xff0c;html5&#xff0c;css3等技术内容和新闻话题&#xff0c;如果你还想近一步学习如何开发&#xff0c;还可以关注我们的极客课程库&#xff0c;里面涵盖了现代开发技术的‘学’与‘习’的全新功能。希望对大家有所帮助…

使用 Spring Cloud 实现微服务系统

使用 Spring Cloud 实现微服务系统 准备工作&#xff1a;为了方便创建项目&#xff0c;以及各版本以来关系&#xff0c;此次创建项目使用 Spring Assistant插件。 创建单体服务中心项目 启用服务端的服务注册&#xff0c;发现功能 EnableEurekaServer SpringBootApplication pu…

android 小工具:pc 上用 curl 命令打开手机浏览器,浏览指定网址

测试 API 时或其它情况经常需要在手机浏览器中输入 url 一长串的 url 输起来真是麻烦 AirDroid 很强大也不用数据线&#xff0c;但有时老断开连接&#xff0c;不是很爽。发到手机 qq 吧还得手动粘贴 所以自己开发了一个小工具 pc 上用 curl 发一条命令&#xff0c;命令中输入要…

iOS: How To Make AutoLayout Work On A ScrollView

转载自&#xff1a; http://natashatherobot.com/ios-autolayout-scrollview/ Posted on June 11th, 2014 Ok, I’ll admit. I’ve been seriously struggling with AutoLayout ever since it’s been introduced. I understand the concept, and I LOVE the idea of it, but w…