网络流

【网络流】——P2764 最小路径覆盖问题

戏子无情 提交于 2019-11-29 00:45:29
一个最小路径覆盖的模板题。 Go: 洛谷 最小路径覆盖=顶点数-二分图最大匹配 因此我们将点复制一份,按照题目给的数据在两端连边,长度为1。 建立一个super源&汇,源向左边的点连边,右边的点向汇连边,长度为1。 求解路径: 我们在邻接表中存下每条边的起始点,对于一条流为0的边,表示它是最小路径中的一条,那么用冰茶姬将他们连起来,最后访问单独集合中的路径即可。 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 6e5+10,inf = 1e9; 4 int n, m, S, T, ans, d[N],head[N],maxflow,vis[N],f[N]; 5 int tot=-1; 6 struct edge{ 7 int w; 8 int next; 9 int to; 10 int from; 11 }e[N]; 12 int getf(int x){ 13 return f[x]==x?f[x]:f[x]=getf(f[x]); 14 } 15 inline void addedge(int x, int y, int z) { 16 e[++tot].to=y; 17 e[tot].next=head[x]; 18 e[tot].w=z; 19 e[tot].from=x; 20 head

有上下界的网络流

一曲冷凌霜 提交于 2019-11-28 20:10:34
有上下界的网络流 给定一个网络,一个加权的有向图G,其中的每条边都有一个容量上界C。其中的两点:S只有出度没有入度,T只有入度没有出度。求S到T最大可以流过的流量,这是最大流的模型。 且满足以下条件: 容量限制:每条边的流量 0 ≤ f ≤ C 0≤f≤C 0 ≤ f ≤ C 流量平衡:任意一个点 i i i , ∑ ( u , i ) ∈ E f ( u , i ) = ∑ ( i , v ) ∈ E f ( i , v ) \sum_{(u,i)\in E}f(u,i)=\sum_{(i,v)\in E}f(i,v) ∑ ( u , i ) ∈ E ​ f ( u , i ) = ∑ ( i , v ) ∈ E ​ f ( i , v ) (除了S,T节点) 这就是一个有源点和汇点的网络流模型 如果将条件1改为 B ≤ f ≤ C B\leq f \leq C B ≤ f ≤ C 那么该模型就变成了有上下界的网络流模型 如果再将条件2中的除了S,T节点去掉,那么该模型就变为无源汇上下界网络流 现在我们考虑如何判断无源汇网络流的可行流。 我们会求网络流的最大流,也会判断网络流是否有可行流,所以我们的思路是如何把 无源汇上下界网络流 变成 网络流 ?也就是把那个下届去掉。 看下面这个图 上面那副图是一个 无源汇上下界网络流 ,我们现在把他的下届单独拿出来,形成一个新的边,(C为上界

网络流24题——负载平衡问题

隐身守侯 提交于 2019-11-28 19:57:56
题目描述 G G 公司有 n n 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等。如何用最少搬运量可以使 n n 个仓库的库存数量相同。搬运货物时,只能在相邻的仓库之间搬运。 建模分析: 首先先计算出他们的平均数,用每个数都减去平均数得到新的值,这个值如果是负数意味着需要从别的地方搞过一点来,如果正数就说明可以往外送一点. 我们建立超级源点和超级汇点(这套路很常见的) 如果权值为正,即储存量大于平均值,我们就从s向它连一条边,最大流为: 储存值-平均值 ,费用为0,图论意义就是它可以从源点免费获得多出来的储存值-平均值的流量,就相当于自身有储存值-平均值的流量,上面不是说了吗,建一个超级源点,就是代替这个功能. 如果权值为负,即储存值小于平均值,我们就从它向t连一条边,最大流量为 平均值-储存值 ,费用为0,图论意义就是它必须从别的节点传来流量,并且汇入自身,意义类比与上面所说. 对于每一个可以互相传的节点,即左邻居和右邻居,需要分别向他们连边,表示自己的流可以流过去. 这是单点做法,还可以拆点,还有贪心做法,可参见均分纸牌。 代码: 1 #include<bits/stdc++.h> 2 #define INF 2147483647 3 using namespace std; 4 queue<int> q; 5 int n,m,len,st,ed,ans; 6

网络流24题——负载平衡问题

雨燕双飞 提交于 2019-11-28 19:57:12
负载平衡问题: 现有 n 个仓库,初始状态下每个仓库中有一些货物,且各仓库中数量不等。仓库只能向相邻的仓库搬运货物。现在想要让各个仓库的货物都相等,请求出最小的搬运量。输入 n ,初始状况下每个仓库的货物量,输出最少搬运量(输入保证初始货物量的平均数为整数)。 这题有许多解法,比如说贪心。不过它是网络流24题,网络流也可以解。 这道题要求一个最小的值,想到费用流。题解里有许多很玄妙的建图方法,不过最暴力的建图莫过于: 设初始时仓库 i 中货物量为 start i ,它们的平均数为 aver 。每个仓库建一个点,另外建立源点 S 和汇点 T 。对于仓库 i ,首先从 S 连接一条容量为 start i ,费用为 0 的边,表示初始时这个仓库有这么多货物可以调用;再向T连接一条容量为 aver ,费用为 0 的边,表示最后这个仓库应该有这么多货物。这些都不算作搬运,因此费用都为 0 。 接下来处理仓库间的边。由于我们是暴力做法,因此按题意,每个仓库向相邻仓库各建一条容量为 +∞ ,费用为 1 的边,表示这个仓库可以向两侧输送任意的货物,但这种搬运计入总代价,所以费用为 1 。写代码的时候可以把 +∞ 改为货物总量。 由于最大流已经确定为货物总量(因为连向 T 的边只有 n 条容量为 aver 的边, S 的出边的容量和也为货物总量),因此可以在这张图上跑费用流,最小费用就是题目的解

【网络流24题】负载平衡问题

狂风中的少年 提交于 2019-11-28 19:56:44
这又是一道我没有当场想出来的题 题面 https://www.luogu.org/problemnew/show/P4016 题解 $S$连初始状态,末状态连$T$,转移边流量为$INF$,费用为$1$。 #include<cstdio> #include<cstring> #include<iostream> #include<vector> #include<queue> #define N 105 #define INF 1000000007 #define T (n+1) #define S 0 #define LL long long #define ri register int using namespace std; int n,a[N]; struct graph { vector<int> to,w,c; vector<int> ed[N]; LL dis[N]; int cur[N]; bool vis[N]; void add_edge(int a,int b,int aw,int ac) { to.push_back(b); w.push_back(aw); c.push_back(ac); ed[a].push_back(to.size()-1); to.push_back(a); w.push_back(0); c.push_back(-ac); ed

网络流概念+EdmondKarp算法+Dinic(Dinitz)

半城伤御伤魂 提交于 2019-11-28 19:21:02
网络流问题在实际解决题目中有很多用处 有时可与二分图匹配相搭配(然而我还没有学二分图匹配2333) 所以我还是决定学一下网络流 于是便有了这篇博客 废话不多说 先介绍下概念 关于网络流的基本概念 图,边,点 设边(Edge)的集合为E 点(vertex)的集合为V 图为G 则G=(V,E) \(\color{pink}{S指源点(起点),T指汇点(终点)}\) \(\color{pink}{注意,这里E和V是集合,而G是一个二元组}\) \(\color{pink}{二元组:数据结构的一种(不是指信息的,也许信息也有 雾),二元组(D,R),D为数据元素的有限集,R为D的关系之间的有限集}\) \(\color{pink}{明显这里D指V,R指E}\) 容量网络 G(V,E)只不过要求 有向 相邻两点间的最大边大于0(c(u,v)>0) 则称G为容量网络 弧的流量 话说 我不懂为什么都叫它弧不叫边的2333 即实际流量用f(u,v)表示 网络流 即集合 f = { u \(\in\) V,v \(\in\) V-{u}|f(u, v) } 可行流 0 ≤ f(u,v) ≤ c(u,v) 平衡条件除源点S和汇点T外流入流量总和=流出流量总和 增广路 即一条从S到T的路径且路径上每条边残留容量都为正(c(u,v)-f(u,v)>0) 增广 将S到T的一条增广路拿出来,设其中的最小边权

[CQOI2014]危桥 [网络流 最大流]

此生再无相见时 提交于 2019-11-28 16:16:22
[BZOJ3504] [luoguP3163] #include<iostream> #include<cstdio> #include<queue> #include<cstring> #include<cmath> #include<stack> using namespace std; #define Min(x,y) ((x)<(y)?(x):(y)) const int N=100+50,M=40000+5,inf=0x3f3f3f3f,P=19650827; int nw,n,a1,a2,an,b1,b2,bn,s,t,pre[N],incf[N]; char S[N][N]; template <class t>void rd(t &x){ x=0;int w=0;char ch=0; while(!isdigit(ch)) w|=ch=='-',ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); x=w?-x:x; } int head[N],tot=1; struct edge{int v,flo,nxt;}e[N*N<<1]; void add(int u,int v,int flo){ e[++tot]=(edge){v,flo,head[u]},head[u]=tot;

cogs 728. [网络流24题] 最小路径覆盖问题 匈牙利算法

你说的曾经没有我的故事 提交于 2019-11-28 13:06:25
728. [网络流24题] 最小路径覆盖问题 ★★★☆ 输入文件: path3.in 输出文件: path3.out 评测插件 时间限制:1 s 内存限制:128 MB 算法实现题8-3 最小路径覆盖问题(习题8-13) ´问题描述: 给定有向图G=(V,E)。设P是G的一个简单路(顶点不相交)的集合。如果V中每个 顶点恰好在P的一条路上,则称P是G的一个路径覆盖。P中路径可以从V的任何一个顶 点开始,长度也是任意的,特别地,可以为0。G的最小路径覆盖是G的所含路径条数最少 的路径覆盖。 设计一个有效算法求一个有向无环图G的最小路径覆盖。 提示: 设V={1,2,... ,n},构造网络G1=(V1,E1)如下: 每条边的容量均为1。求网络G1的(x0,y0)最大流。 ´编程任务: 对于给定的给定有向无环图G,编程找出G的一个最小路径覆盖。 ´数据输入: 由文件input.txt提供输入数据。文件第1行有2个正整数n和m。n是给定有向无环图 G的顶点数,m是G的边数。接下来的m行,每行有2个正整数i 和j,表示一条有向边(i,j)。 ´结果输出: 程序运行结束时,将最小路径覆盖输出到文件output.txt中。从第1行开始,每行输出 一条路径。文件的最后一行是最少路径数。 输入文件示例 input.txt 11 12 1 2 1 3 1 4 2 5 3 6 4 7 5 8 6 9

网络流总结

蓝咒 提交于 2019-11-28 12:38:14
网络流题型总结 负载平衡问题: N个环形排列的点,每个点之间的权值数量不相等,现在可以让每个点G 公司有 n 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等。如何用最少搬运量可以使 n个仓库的库存数量相同。搬运货物时,只能在相邻的仓库之间搬运。 题解: 首先为了让每个点收支达到平衡,我们可以先求出所有货物的数量,进而求得每个点货物数量的平均值。 那么对于当前仓库有两种可能: 1当前仓库的数量是比平均值大的,那么我们知道当前仓库是需要流出w[i]-avg数量的。 2当前仓库的数量是比平均值小的,那么我们知道当前仓库是需要流入avg-w[i]数量的 对于情况1,我们让这个点和汇点建立一个边,流量上限是w[i]-avg,费用为0,代表这个边必须流满。 对于情况2,我们让这个点和源点建立一条边,流量上限是avg-w[i],费用为0,代表这个边同样必须流满。 现在考虑单点,由于可以在相邻的点之间传递,我们在相邻点之间,建立一条流量上限为INF ,费用为1的边,代表每向这个点流入一个流量,费用为1。 这样跑一个最小费用最大流,就是本题的答案。 P4015 运输问题: W 公司有 m 个仓库和 n个零售商店。第 i个仓库有 ai ​ 个单位的货物;第 j 个零售商店需要 bj个单位的货物。 货物供需平衡,即n个零售店需要的和m个仓库所拥有的货物相同 从第 i 个仓库运送每单位货物到第