网络流

【网络流相关】最大流和费用流的EK算法实现

北城余情 提交于 2019-12-23 02:18:15
Luogu P3376 最大流是网络流模型的一个基础问题。 网络流模型就是一种特殊的有向图。 概念: 源点:提供流的节点,类比成为一个无限放水的水厂 汇点:接受流的节点,类比成为一个无限收水的小区 弧:类比为水管 弧的容量:类比为水管的容量;用函数 \(c(x,y)\) 表示弧 \((x,y)\) 的容量 弧的流量:类比为当前在水管中水的量;用函数 \(f(x,y)\) 表示弧 \((x,y)\) 的流量 弧的残量:即容量-流量 容量网络:对于一个网络流模型,每一条弧都给出了容量,则构成一个容量网络。 流量网络:对于一个网络流模型,每一条弧都给出了流量,则构成一个流量网络。 残量网络:对于一个网络流模型,每一条弧都给出了残量,则构成一个残量网络。最初的残量网络就是容量网络。 对于网络流模型 \(G=(V,E)\) ( \(V\) 为点集, \(E\) 为边集)有如下性质: 流量守恒:除了源点与汇点之外,流入任何节点的流一定等于流出该节点的流 容量限制: \(\forall (x,y) \in E,有0<=f(x,y)<=c(x,y)\) 斜对称性: \(\forall (x,y) \in E,有f(x,y)=-f(y,x).\) 类似于函数奇偶性中的奇函数,或者是矢量的方向。 最大流问题,用通俗的方式解释就是从源点S到汇点T输送流量,询问最多有多少流量能输送到汇点。 对于这样的问题

网络流专题

血红的双手。 提交于 2019-12-21 01:04:35
仔细思考了一下,发现自己还有许多弱项,网络流也是其中之一,而且只会写板子,需要补一补。 还有10天就GDOI了,要抓紧啊…… 注意:以下某些题没有写代码,只是口胡后看了题解发现差不多,不保证完全正确。 本专题的题单来自 https://www.cnblogs.com/xht37/p/10457051.html ,Orz神仙 二分图 洛谷P1402 酒店之王 把每个人拆成两个点放在中间,左边房子右边菜,跑最大流即可。 洛谷U64949 棋盘覆盖 黑白染色之后发现只能黑和白匹配,于是就是个二分图了,搞出最大匹配即可。 套路:黑白染色之后有可能会成为二分图。 洛谷U64970 車的放置 把行和列作为点,格子作为边,如果可以放就把对应的行列连起来,然后跑最大匹配。 这样的匹配显然满足所有车都不同行不同列。 套路:行列作为点,格子作为边。 洛谷P1129 [ZJOI2007]矩阵游戏 注意到一个性质:无论怎么换,同行的黑点仍然同行,同列的黑点仍然同列。 所以每行/列最多有一个黑点在对角线上。 那么和上一题一样的建图方法就可以做了。 洛谷P1963 [NOI2009]变换序列 显然在 \(D(i,T_i)\) 确定的情况下能与 \(i\) 匹配的 \(T_i\) 是常数级别的。 那么连一下二分图就可以得到一组解了。 用匈牙利算法,从后往前做,就可以字典序最小了。 UVA1194 Machine

[学习笔记]网络流24题

落花浮王杯 提交于 2019-12-17 19:11:03
不按24题的顺序,按我做题的顺序 1、飞行员配对方案问题 建个图,跑遍匈牙利,让飞行员给其对应的飞机连一条边 #include <bits/stdc++.h> using namespace std; const int maxn=10000+10; int n,m,e,head[maxn],to[maxn<<1],nxt[maxn<<1],vis[maxn],tot,ans,match[maxn]; inline void add(int x,int y){ to[++tot]=y; nxt[tot]=head[x]; head[x]=tot; } int dfs(int x){ for(int i=head[x];i;i=nxt[i]){ int y=to[i]; if(!vis[y]){ vis[y]=1; if(!match[y]||dfs(match[y])){ match[y]=x;return 1; } } } return 0; } int main() { scanf("%d%d",&n,&m); int x,y;scanf("%d%d",&x,&y); while(x!=-1&&y!=-1){ if(x<=n&&y<=n+m) add(x,y); scanf("%d%d",&x,&y); } for(int i=1;i<=n;i++){ memset(vis,0

hdu 1956 (网络流解决欧拉回路)

冷暖自知 提交于 2019-12-17 13:46:35
题目连接:https://vjudge.net/problem/HDU-1956 题意:给定一些点和一些边,有些边是有向的,,有些边是无向的,求是否存在欧拉回路。 题解:想不到的网络流。 混合图: 即有的边有向,有的边无向。 定义: 对于图G的一个回路,若它恰通过G中每条边一次,则称该回路为 欧拉(Euler)回路 。 具有欧拉回路的图称为 欧拉图 (简称E图)。 定理 : 一个无向图是欧拉图,当且仅当该图所有顶点度数都是偶数。 一个有向图是欧拉图,当且仅当该图所有顶点度数都是0。 有向图存在欧拉回路的充要条件:基图(把所有有向边变成无向边以后得到的图)连通,且每个点的出度等于入度。 所以求混合图的关键是:判断能否存在一个定向,使得每个节点的入度等于出度。 建图过程。 在原图中,首先给每条无向边任意定向,构成一个有向图,计算每个点的度deg,入度为正,出度为负,如果某个点的deg为奇数,显然不存在欧拉回路。由于原来的有向边,不能更改方向,无用,删了,对原图中的无向边定向后构成的有向图,如果点 i 到j 有一条弧,弧< i , j >容量加1(i 到 j 有多条边的时候,即有重边,可以一条边,多容量代替) 增加源点S,汇点T,对于每个点 i ,如果deg < 0,即出度大于入度,从S引一条弧到 i ,容量为(- deg ) / 2;如果deg > 0, 即入度大于出度,从 i

图论总结

你。 提交于 2019-12-17 07:43:55
一、最短路   最短路常见算法包括堆优化Dijkstra、Bellman-Ford、SPFA、Floyd。   Dijkstra的时间复杂度为O(mlongn),但是但是不能处理负边权。   基于“松弛”操作(或称三角形不等式)的Bellman-Ford时间复杂度为O(nm),可以处理负边权。队列优化的Bellman-Ford,即SPFA,时间复杂度降到了O(km)(k通常为一个较小的常数),但是在特殊构造的图(比如网格图)中容易退化,因此有的大佬建议尽量不要在正式比赛中使用SPFA。   SPFA也可用于差分约束系统,将在第十部分讲解。   与前三种基于贪心的单源最短路不同,基于动态规划的Floyd是一种多源最短路算法,还可以用于求传递闭包等,但时间复杂度达到了O(n 3 ),无法处理较大的数据。   考场上一般不会考裸的最短路,次短路和最短路计数估计也不常考。我个人觉得真正可能作为考题出现的是最短路树,即由某一点出发的最短路上的边构成的树。众所周知,树拥有许多优秀的性质,也因此常常作为考点。放上几道题:   WOJ #3771 「一本通 3.1 例 1」黑暗城堡(比较裸的最短路树)   WOJ #2423 安全出行Safe Travel(USACO的题)    WOJ#4709 迷路 (某道校内模拟赛题)   最短路也可以与其它算法结合:   WOJ #3841 双调路径

习题:切糕(网络流)

微笑、不失礼 提交于 2019-12-16 13:07:28
题目 传送门 思路 将蛋糕割开,不就相当于切开一些边 同时又要要求值最小,所以比较明显的最小割 我们主要考虑如何将当前点的权值转换成边的容量 也很简单,将当前点向下一层的节点连一条容量为当前点的权值的边就行了 那么最后一层呢? 建一层虚层就行了。 对于D的限制 我们只需要将距离不超过D的点对之间连INF的边就行了 代码 #include<iostream> #include<cstring> #include<climits> #include<queue> using namespace std; int p,q,r; int d; int a[45][45][45]; struct network_edge_dinic { #define maxn 724005 int s,t; int cnt; int cur[maxn]; int head[maxn]; int to[maxn<<1]; int val[maxn<<1]; int nxt[maxn<<1]; int d[maxn]; #undef maxn void init() { cnt=1; } void add_edge(int u,int v,int w) { to[++cnt]=v; val[cnt]=w; nxt[cnt]=head[u]; head[u]=cnt; to[++cnt]=u; val[cnt]

「网络流」

雨燕双飞 提交于 2019-12-11 06:14:24
网络流专题还有3个题,就暂时告一段落了。 分类 最大流,费用流,可行流,上下界 有/无源汇 最大/最小/可行 void/费用 流。 写在前面 本blog例题顺序与难度无关,与校内OJ的顺序挂钩。 开始 我接触的网络流里模板大概有isap,dinic,EK,zkw,其实模板很简单,建边才是重点 奇怪的游戏 奇偶染色是基础,我们 并不能 发现,假设最后变成的数是x,奇格子的原数和sum1,数量a1,偶格子的原数和sum2,数量a2,那么一定满足a1*x-sum1=a2*x-sum2(增量相同),也就是(a1-a2)x=sum1-sum2,如果不是奇奇图(n,m都为奇)的话,a1!=a2,那如果能变成一个数,最后的x就一定是(sum1-sum2)/(a1-a2),但这个x一定要大于等于最大的数。如果不是这种情况,那么最后变成的数一定就具有二分的性质(因为奇格子=偶格子),那么我们二分最后变成的数,建图跑最大流看是否满流 建图方式:设二分数为mid,lnk(S,奇,mid-原值),lnk(偶,T,mid-原值),lnk(i,四周,inf)。按奇偶二分图,每个点向四周连边 士兵占领 “至少”这个条件对网络流很不友好,就转化一下条件,变成咩行咩列最多不放的士兵个数,求最多不放的士兵个数,就是网络流的基础型了 建图方式:二分图 紧急疏散evacuate 二分答案mid是基础

网络流

会有一股神秘感。 提交于 2019-12-11 03:04:29
最大流/最小割 增量建图 最大权闭合子图 二分检验 最小割一定要找全矛盾关系,如文理分科 选文选理,同选文同选理矛盾 最大流的一个单位流量经过的点代表的是这个点的特征 最小割就是如果能从S到T,那么这条路就是非法的,如果单个点矛盾关系不是很多,可以建立每个点和所有矛盾关系之间的 先处理好局部的关系,再拓展到全局,如:employ人员雇佣 对于两点a,b之间存在 选a选b 减去$c_a,c_b$ 选a,b其中一个 减$E_{a,b}*2,c_a/c_b$,不选a,b减$E_{a,b}$ 然后可以发现,如果不选i,那么所有的$E_{i,j}$都得不到,所以可以连边表示$sum_i$与$c_i$的取舍关系,发现只选一个还要多减,再连边$a->b,b->a$ 这样如果两条与源点相连的边被割掉合法,两条与汇点割掉也合法,当只有一个割掉的时候,S与未选点之间还是有流量,流向所有的已选点,满足题意。 1 inline bool bfs() 2 { 3 memset(d,0,sizeof d); 4 d[q[h=t=0]=S]=1;hd[S]=head[S]; 5 while(h<=t) 6 { 7 int x=q[h++]; 8 for(int i=head[x],y;i;i=nxt[i]) 9 { 10 if(!val[i]||d[y=to[i]]) continue; 11 d[q[++t]

网络流(dinic算法)

风格不统一 提交于 2019-12-11 00:55:45
洛谷p3376 https://www.luogu.com.cn/problem/P3376 #include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <cstring> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; const int maxn = 1000000 + 5; int n,m,be,en; queue<int>q; int to[maxn]; int cost[maxn]; int head[maxn]; int nex[maxn]; int cnt; void add(int x,int y,int z) { cnt++; nex[cnt]=head[x]; //先把指针指向上次的位置 head[x]=cnt; //然后把头指向自己 to[cnt]=y; cost[cnt]=z; } int level[maxn]; bool bfs() //深度打表(分层) { memset(level,-1,sizeof(level)); level[be]=0; q.push(be); while(!q.empty()) { int u=q.front(); q.pop();

网络流总结

馋奶兔 提交于 2019-12-10 20:45:30
联赛后按专题刷题,最近是网络流,感觉自己每到刷题时就会很慢,好在最近状态还可以。 然而 老夫思考一番决定还是放题解包吧,从题解中寻找思路。 关于最大流: 首先是一些比较基础的方法,如:拆点,先把总的贡献加上再尽量减小(把至少转化成最大) 以及一些建图技巧:奇偶染色,按照某个限制进行拆点,动态加点等 例题: 蜥蜴(基础题,拆点限流 星际战争(与二分结合 奇怪的游戏(奇偶染色 士兵占领(先加贡献,减最大流 紧急疏散(按时间拆点 个人理解:最大流的题难点其实在于建图方式,对转化题意方面要求不高 关于最小割 : 需要一定的转化题意的能力, 首先是类似二分图,对两点间有限制的,如:二选一。可以用最小割解决 其次是可以转化为最大权闭合子图的。 技巧方面,注意数据范围如果很大看能不能转化为对偶图跑最短路 例题: 狼抓兔子&海拔(平面图转对偶图 切糕(可以算是一类模型,用inf边去限制割的边的范围 最大获利&植物大战僵尸&寿司餐厅&employ人员雇佣&线性代数(最大权闭合子图 happiness(用最小割实现一个类似比较大小的过程 另外:最小割树(这玩意我只会板子。。。 个人理解:最小割在某些情况下可以理解为比较大小的过程。( 好像就是最大权闭合子图 另外:若可以导出“若i则j,所选权值最大”之类的东西,可以考虑最大权闭合子图 关于费用流(只会spfa