【文文殿下】网络流学习笔记
最大流算法
Dinic
割
一个网络的割:存在一个边集,删去集合里的边时,S-T不再连通
最小割
所有割中边权之和最小的
最小割-最大流定理
最小割等于最大流
二分图匹配
\(M\)为边集\(E\)的一个子集,如果对于任何一个点,都最多被\(M\)中一条边覆盖,则成\(M\)为一个匹配。
最大匹配
使\(|M|\)最大的一个匹配(可能有多个)
最大匹配求法
源点S向所有X连边,Y向T连边,容量均为1,原始图上边容量均为1,最大流=最大匹配。
二分图最小顶点覆盖
\(V'\)是点集\(V\)的一个子集,对于任意一条边,至少有一端在\(V'\)内。
最小的一个\(V'\)被称作最小顶点覆盖
最大匹配=最小顶点覆盖
证明:若有一条边未覆盖,则匹配+1,与最大匹配矛盾
二分图最大独立集
\(V'\)是\(G\)的一个独立集,当且仅当对于任何一条边,它至少有一端不在\(V'\)内
最大独立集大小等于\(|V|-\)最大匹配
证明:最小割。若(S,x)为割边,则在\(V'\)中删去x。y同理。
有向图最小路径覆盖
用尽可能少的简单路径覆盖整张图。特殊的:一个点也是一条简单路径。
二分图建模:把每个点\(x\)拆成\(x_1,x_2\),分别属于X,Y.
对原图一条边,(x,y),链接(\(x_1,y_2\))
易证:最小路径覆盖=\(|V|-\)最大匹配。
X中未被匹配的点是每条路径的起点
二分图点权最大独立集
最大权独立集=\(\sum value(x) -\)最小权顶点覆盖
最小权覆盖=最大匹配=最小割=最大流(原图的边流量为无穷大)
建图:S向所有X连边,容量为value(x),所有的Y向T连边,容量为value(y) ,原图中的边容量为无穷大
最大权闭合子图
\(U\)是\(G\)的一个子图,x属于\(U\) 当且仅当对于任何一条边(x,y),y也属于\(U\),那么\(U\)是\(G\)的一个闭合子图
权值和最大的闭合子图称为最大权闭合子图(权值有正有负)
求法:建立源点S,向所有x(value(x)>0)连边,容量为value(x),建立汇点T,所有y(value(y)<0)向T连边,容量为-value(y),对于原图中的边(x,y),在x,y之间连一条容量为无穷大的边。
最大权闭合子图=\(\sum_{value(x)>0} value(x) -\) 最小割
证明:
若选了一个点x,则他的后继一定会选(最大流),满足闭合子图。
若一个(S,x)为割边,说明(S,x)满流,则选了x,他的后继付出的代价一定不小于x的权值,即x的贡献小于等于0
有节点容量的最大流
建图:对于每一个点x拆成两个点\(x_1,x_2\),对于所有入边,链接\(x_1\)出边从\(x_2\)出,\(x_1,x_2\)之间链接一条容量为节点容量的边
上下界网络流
每条边有流量上界和流量下界
建图:先建新源点S1,新汇点T1,对于一条边(x,y) ,从x到y连一条\(c(e)-l(e)\)的边,从S1向y连一条\(l(e)\)的边,从x向T1连一条\(l(e)\)的边。
建一条从T到S容量为k的边。
存在可行流:从S1出发的所有边都满流。
最小流:二分K,存在可行流,最小的K即为最小流
最大流:先跑可行流。跑完以后,把自己加入的必要弧删去,再恢复源汇,尝试增广S-T
费用流
算法:ZKW费用流
板子
最大流(BZOJ1694)
#include<cstdio>
#include<cstring>
#include<queue>
const int maxn = 1010;
const int maxm = 2e5+10;
const int inf = 0x3f3f3f3f;
int n,k,S,T,wet[maxm],nxt[maxm],to[maxm],hd[maxn],cnt=1,dis[maxn],cur[maxn];
std::queue<int> Q;
inline void add(int u,int v,int w) {nxt[++cnt]=hd[u];hd[u]=cnt;to[cnt]=v;wet[cnt]=w;
}
inline bool bfs(void) {for(int i = 0;i<=T;++i) cur[i]=hd[i];memset(dis,0,sizeof dis);dis[S]=1;Q.push(S);while(!Q.empty()) {int u = Q.front();Q.pop();for(int i = hd[u];i;i=nxt[i]){ int nx = to[i];if(!dis[nx]&&wet[i]>0) {dis[nx]=dis[u]+1;Q.push(nx);}}}return dis[T]!=0;
}
inline int dfs(int u,int flow) {if(u==T) return flow;int tmp = 0;for(int &i = cur[u];i;i=nxt[i]) {int nx = to[i];if(dis[nx]==dis[u]+1&&wet[i]>0) {int ret = dfs(nx,std::min(flow,wet[i]));if(ret<0) ret=0;flow-=ret;tmp+=ret;wet[i]-=ret;wet[i^1]+=ret;if(flow==0) break;}}return tmp;
}
inline int dinic(void) {int flow = 0;while(bfs()) {flow+=dfs(S,inf);}return flow;
}
int main() {scanf("%d%d",&n,&k);for(int i = 0;i<k;++i) {int x,y;scanf("%d%d",&x,&y);add(x,n+y,1);add(n+y,x,0);}S = 0;T = n+n+1;for(int i = 1;i<=n;++i) {add(S,i,1);add(i,S,0);}for(int i = n+1;i<=n+n;++i) {add(i,T,1);add(T,i,0);}printf("%d",dinic());return 0;
}
费用流
#include<cstdio>
#include<cstring>
#include<queue>
typedef long long ll;
const int maxn = 5050,maxm=1e5+10;
const int inf = 0x3f3f3f3f;
int n,m,S,T,cnt=1,wet[maxm],fee[maxm],hd[maxn],nxt[maxm],to[maxm];
int dis[maxn],cur[maxn];
bool vis[maxn];
std::queue<int> Q;
inline void add(int u,int v,int w,int f) {nxt[++cnt]=hd[u];to[cnt]=v;wet[cnt]=w;fee[cnt]=f;hd[u]=cnt;
}
inline bool spfa(void) {memset(dis , 0x3f3f3f3f , sizeof dis);memset(vis, 0 , sizeof vis);for(int i = 1;i<=n;++i) cur[i]=hd[i];Q.push(S);dis[S]=0;while(!Q.empty()) {int u = Q.front();Q.pop();vis[u]=0;for(int i = hd[u];i;i=nxt[i]) {int nx = to[i];if(dis[nx]>dis[u]+fee[i]&&wet[i]) {dis[nx]=dis[u]+fee[i];if(!vis[nx]) {Q.push(nx);vis[nx]=1;}}}}return dis[T]!=dis[0];
}
inline int dfs(int u,int c,int &flow ,ll &ans) {vis[u]=1;if(u==T) {flow+=c;ans+=dis[u]*c;return c;}int tmp = 0;for(int &i = cur[u];i;i=nxt[i]) {int nx = to[i];if(!vis[nx]&&wet[i]>0&&dis[nx]==dis[u]+fee[i]) {int t = dfs(nx,std::min(c,wet[i]),flow,ans);wet[i]-=t;wet[i^1]+=t;tmp+=t;c-=t;}}return tmp;
}
inline void dinic(void) {int flow = 0;ll ans = 0;while(spfa()) {vis[T]=1;while(vis[T]) {vis[T]=0;dfs(S,inf,flow,ans);}}printf("%d %lld\n",flow,ans);return;
}
int main() {scanf("%d%d%d%d",&n,&m,&S,&T);for(int i = 0;i<m;++i) {int u,v,w,f;scanf("%d%d%d%d",&u,&v,&w,&f);add(u,v,w,f);add(v,u,0,-f);}dinic();return 0;
}
转载于:https://www.cnblogs.com/Syameimaru/p/10117145.html
【文文殿下】网络流学习笔记相关推荐
- [网络流]学习笔记:一次理解网络流!
学一个新算法,总要翻多而杂的blog,收获不多.所以我就致力于把学习笔记总结,希望一遍看懂. 简单入门 (但是不全) 一.从概念入手 网络流用于解决流量问题 网络流:所有弧上流量的集合f={f(u,v ...
- 《网络流学习笔记04 NYOJ 489 哭泣天使(建边,超级源点和汇点)》
链接:click here 题意描述: 哭泣天使 时间限制: 1000 ms | 内存限制: 65535 KB 难度: 5 描述 Doctor Who乘着Tardis带着Amy来到了一个星球,一开 ...
- 【学习笔记】网络流算法简单入门
[学习笔记]网络流算法简单入门 [大前言] 网络流是一种神奇的问题,在不同的题中你会发现各种各样的神仙操作. 而且从理论上讲,网络流可以处理所有二分图问题. 二分图和网络流的难度都在于问题建模,一般不 ...
- 网络流算法学习笔记——最大流问题基本概念和Ford-Fulkerson方法(标号法C++实现)
屈婉玲<算法设计与分析>第2版第7章网络流算法学习笔记. 基本概念 最大流问题,相当于有从s到t的供水系统,每段路径都有限定流量,除了s.t两地外,每个中间点都不能滞留,从s流入多少,就从 ...
- 算法学习笔记:网络流#4——ISAP 求解最大流
算法学习笔记:网络流#4--ISAP 求解最大流 1. 前言 2. 模板 2.1 详解 2.2 正确性证明 2.3 代码 3. 算法对比 3.1 一般数据下的对比 3.2 特殊数据下的对比 4. 总结 ...
- Go 学习推荐 —(Go by example 中文版、Go 构建 Web 应用、Go 学习笔记、Golang常见错误、Go 语言四十二章经、Go 语言高级编程)
Go by example 中文版 Go 构建 Web 应用 Go 学习笔记:无痕 Go 标准库中文文档 Golang开发新手常犯的50个错误 50 Shades of Go: Traps, Gotc ...
- 《Angular4从入门到实战》学习笔记
<Angular4从入门到实战>学习笔记 腾讯课堂:米斯特吴 视频讲座 二〇一九年二月十三日星期三14时14分 What Is Angular?(简介) 前端最流行的主流JavaScrip ...
- 学习笔记(八)——jQuery(二)
文章目录 一.class 操作 二.Tab 栏切换 三.JQ 动画 四.元素操作 4.1.html() .$()和 empty() 4.2.属性获取.设置.移除 4.3.补充:获取boolean类型的 ...
- 学习笔记(七)——jQuery(一)
Jquey就是一款跨主流浏览器的JavaScript库,简化JavaScript对HTML操作就是封装了JavaScript,能够简化我们写代码的一个JavaScript库 文章目录 一.JQ的引入 ...
最新文章
- 房地产萧条的两个标志
- LINQ那些事儿(2)- 简单对象的CRUD操作和Association的级联操作
- ubuntu idea桌面快捷方式无法启动_每个 Ubuntu 用户都应该知道的键盘快捷键
- 配置IISExpress允许外部访问
- 小白学Python——Anaconda安装
- 最长公共子序列问题解析
- 贪吃蛇小游戏程序(C语言)
- 如何在SSD和HDD VPS主机之间进行选择
- windows cmd打开新窗口关闭窗口
- 嵌入式学习笔记7——LCD1602液晶屏
- 史上ElasticSearch 最全详细使用教程
- 亿万第一至二季/全集Billions迅雷下载
- IntelliJ IDEA设置自动导包方法
- 条形码宽度大小为什么不能任意调整?是打印机问题还是软件问题?
- 数据库 MySQL-window安装和卸载
- 【无标题】warning
- 购买域名和虚拟空间对于建站的必要性
- 高斯赛德尔迭代法(线性方程组求解)
- C#.NET Winform 通用开发框架
- java亲戚称呼计算器_python版亲戚关系计算器