网络流

上下界网络流

两盒软妹~` 提交于 2019-12-01 18:35:08
•参考资料 [1]: 上下界网络流学习笔记 [2]: 上下界网络流问题 [3]: 上下界网络流 •理解 重在处理下界的限制。 对于一条边$u->v$,下界为$l$,上界为$r$。我们可以将这条边变为上界为$r-l$,下界为$0$。 相当于在可行流的基础上每条边的流量都减小了$l$。但是这样做了之后,流量却不守恒了。 流入$v$的流量少了$l$,流出$u$的流量也少了$l4。 所以要增加一个叫附加流的东西,使得这个附加流和我们的初始流合并之后满足流量守恒 即: 如果某个点在所有边流量等于下界的初始流中满足流量守恒,那么这个点在附加流中也满足流量守恒, 如果某个点在初始流中的流入量比流出量多$x$,那么这个点在附加流中的流出量比流入量多$x$. 如果某个点在初始流中的流入量比流出量少$x$,那么这个点在附加流中的流出量比流入量少$x$. $x的值$可以枚举x的所有连边求出。比较方便的写法是开一个数组$du[]$,在输入边的时候,对于出点$u$,$du[u]-=l$,对于入点$v$,$du[v]+=l$ $du[i]$表示i在初始流中的流入量-流出量的值,那么$du[i]$的正负表示流入量和流出量的大小关系 建立一个超级源点$S$和超级汇点$T$,然后枚举所有的点$i$, 如果$du[i]<0$,则加$(i,T,-du[i])$,如果$du[i]>=0$,则加$(S,i,du[i])$

Magic Potion(网络流)

馋奶兔 提交于 2019-12-01 08:49:56
  2018南京的铜牌题,听说学长他们上来就A了,我这个图论选手也就上手做了做,结果一言难尽......   发此篇博客希望自己能牢记自己的菜...      本题大意:有n个heros和m个monsters大战,每个heros只能杀一个monsters且他们只能杀固定编号的monsters,现在有药水k瓶,如果英雄喝了药水那么它又可以多杀一个怪兽,每个英雄最多能喝一瓶药水。现在给你n, m, k,还有n个英雄各自能击杀怪兽的编号,问这些英雄最多能杀多少怪兽。   题解太水,大佬请绕道。。。   我用的网络流,别的都是正常思路,唯一一点就是,药水这个点,我们可以考虑从超级源点起向另一个源点引一条容量为k的边,从这个源点向英雄连一条容量为1的边表示药水。   千万不要像傻逼的我。。。   下面介绍一下我的做法。。。超级源点给附加源点提供药水,然后附加源点给英雄,英雄有一个初始能量?哦好了那我们把英雄拆点成a1, a2,给他a2一个能量就可以了,然后让a2代替英雄做该做的事,具体做法是附加源点给a1药水,a1自己本来有一个能量然后还可以接收药水(起始流量为1,容量为2),a2去打怪兽,然后向超级汇点统计。。。。。。   总的来说我的做法就可以描述为,正解的初始能量是超级源点给的,这本来也是常规思路,我个杠精非得拆点让他兄弟给,至今不明白为什么错了,堪忧。   哦对了

网络流总结

二次信任 提交于 2019-12-01 07:07:14
最大流 #include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f const int N=1e4+10; const int M=1e5+10; struct Edge { int to, next, w; } edge[M<<1]; int head[N],cur[N],pos=1,level[N]; void add(int a, int b, int c) { edge[++pos] = (Edge){b, head[a], c};head[a] = pos; edge[++pos] = (Edge){a, head[b], 0};head[b] = pos; } bool bfs(int s, int t) { memset(level, 0, sizeof level); queue<int> q; level[s] = 1; q.push(s); while (!q.empty()) { int pos = q.front();q.pop(); for (int i = head[pos]; i; i = edge[i].next) { int v = edge[i].to; if (!edge[i].w || level[v]) continue; level[v] = level[pos]

7. 图论

北城以北 提交于 2019-12-01 02:04:50
最短路 最小生成树 树的直径与最近公共祖先 基环树 负环与差分约束 Tarjan算法与无向图连通性 Tarjan算法与有向图连通性 二分图的匹配 二分图的覆盖于独立集 网络流初步 总结与练习 来源: https://www.cnblogs.com/hebust-fengyu/p/11647255.html

【luogu4474王者之剑】--网络流

穿精又带淫゛_ 提交于 2019-11-30 15:05:51
题目描述 这是在阿尔托利亚·潘德拉贡成为英灵前的事情,她正要去拔出石中剑成为亚瑟王,在这之前她要去收集一些宝石。 宝石排列在一个n*m的网格中,每个网格中有一块价值为v(i,j)的宝石,阿尔托利亚·潘德拉贡可以选择自己的起点。 开始时刻为0秒。以下操作,每秒按顺序执行 在第i秒开始的时候,阿尔托利亚·潘德拉贡在方格(x,y)上,她可以拿走(x,y)中的宝石。 在偶数秒,阿尔托利亚·潘德拉贡周围四格的宝石会消失 若阿尔托利亚·潘德拉贡第i秒开始时在方格(x,y)上,则在第i+1秒可以立即移动到(x+1,y),(x,y+1),(x-1,y)或(x,y-1)上,也可以停留在(x,y)上。 求阿尔托利亚·潘德拉贡最多可以获得多少价值的宝石 输入格式 第一行给出数字N,M代表行列数.N,M均小于等于100,宝石的价值不会超过10000.下面N行M列用于描述数字矩阵 输出格式 输出最多可以拿到多少价值宝石 输入输出样例 输入 #1 2 2 1 2 2 1 输出 #1 4 说明/提示 姚金宇的原创题。 代码: include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define R register #define inf 1e9+7 using namespace std

网络流学习总结2

孤人 提交于 2019-11-30 13:29:52
昨天写了网络流的 EK 算法( 写得我自己都不太懂 ),今天再来总结一下另一个网络最大流的算法 Dinic 。 先来介绍一个概念:残量网络。 一个网络中所有剩余容量大于0的边和与这些边相连的节点组成这个网络的残量网络。 我们回忆一下EK算法的过程: 1.在网络中寻找一条剩余容量大于0的边,把它加入到增广路中。 2.依据找到的增广路,更新边的剩余容量和最大流。 所以,我们每次对增广路的搜索,都可能需要对整个残量网络进行遍历,而只找到一条增广路,还可以进一步优化。 在这里,我们提出了节点的层次d[x],它表示从s到x最少需要经过的边数。在残量网络中,满足d[y] = d[x] + 1的所有边(x , y)构成的子图被称为 分层图 。显然,它是一张有向无环图。 而传说中的 Dinic 算法就是通过以下两个步骤来求最大流: 1.在残量网络中不断通过BFS构造分层图,直到s不能到达t。 2.在分层图上用DFS求增广路,在回溯时更新剩余容量。 好啦,大体的介绍完了,具体是怎么回事呢??( 其实我也不太懂 ) 在BFS时,我们每找到一个节点x,它到s的最少边数d[x]一定已经求得,那么所有以x为起点的边(x , y)(剩余容量大于0)都可以成为分层图中的子图,于是我们把所有与x相连的节点y的d[y](它还没有被赋值)都更新为d[y] = d[x] + 1,因为只需要多走一条边就可以到y了。这样

网络流建模总结

爱⌒轻易说出口 提交于 2019-11-30 01:48:58
最小路径覆盖 将一个点拆分为入点和出点,原图的最小路径覆盖=原图的边数-新图的最大匹配 二分图最小点覆盖 最小点覆盖=最大匹配 二分图最大独立集 最大独立集=点数-最小点覆盖 二分图最小边覆盖 最小边覆盖=点数-最小点覆盖 二分图最小点权覆盖 原二分图中的边(u,v)替换为容量为INF的有向边(u,v),设立源点s和汇点t,将s和x集合中的点相连,容量为该点的权值;将y中的点同t相连,容量为该点的权值。在新图上求最大流,最大流量即为最小点权覆盖的权值和。 二分图最大权独立集 最大权独立集=总权值-最小点覆盖 来源: https://www.cnblogs.com/happyLittleRabbit/p/11544499.html

透彻网络流-wfx-最大流

给你一囗甜甜゛ 提交于 2019-11-29 15:01:36
前提: 我们想象一下自来水厂到你家的水管网是一个复杂的有向图,每一节水管都有一个最大承载流量。自来水厂不放水,你家就断水了。但是就算自来水厂拼命的往管网里面注水,你家收到的水流量也是上限(毕竟每根水管承载量有限)。你想知道你能够拿到多少水,这就是一种网络流问题。 在网上找了很久资料,虽然讲解网络流的资料很多但是浅显易懂的很少 (可能是我太蒻了吧) ,写这篇文章只希望点进来的人都能学会网络流 (都能点赞) 首先 最大流: 何为最大流 简单来说就是水流从一个源点s通过很多路径,经过很多点,到达汇点t,问你最多能有多少水能够到达t点。 结合图示理解: 从s到t经过若干个点,若干条边,每一条边的水流都不能超过边权值(可以小于等于但不能大于),所以该图的最大流就是10+22+45=77。 如果你还是不能理解,我们就换一种说法,假设s城有inf个人想去t城,但是从s到t要经过一些城市才能到达,(以上图为例)其中s到3城的火车票还剩10张,3到t的火车票还剩15张,其他路以此类推,问最终最多能有多少人能到达t城? EK: Edmond—Karp 增广路: 增广路: 增广路是指从s到t的一条路,流过这条路,使得当前的流(可以到达t的人)可以增加。 那么求最大流问题可以转换为不断求解增广路的问题,并且,显然当图中不存在增广路时就达到了最大流。 具体怎么操作呢? 其实很简单,直接从s到t广搜即可

网络流之二者取一式问题

安稳与你 提交于 2019-11-29 05:03:34
网络流之二者取一式问题: 大致是说有n个人,有两个阵营,把人分成相应的阵营会有对应的价值,可能还会有联立的价值(就是规定如果u号选了A,v号选了B就有额外的价值什么的); 这种问题往往是转换为最小割问题,然后跑出最大流,如果题目要求是求 最大的价值 那就把全部边的答案相加在减去最大流 1 ) https://www.luogu.org/problem/P1361 题目描述 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子有1个(就是可以种一棵作物)(用1...n编号)。 现在,第i种作物种植在A中种植可以获得ai的收益,在B中种植可以获得bi的收益,而且,现在还有这么一种神奇的现象,就是某些作物共同种在一块耕地中可以获得额外的收益,小M找到了规则中共有m种作物组合,第i个组合中的作物共同种在A中可以获得c1i的额外收益,共同总在B中可以获得c2i的额外收益。 小M很快的算出了种植的最大收益,但是他想要考考你,你能回答他这个问题么? 输入格式 第一行包括一个整数n 第二行包括n个整数,表示ai第三行包括n个整数,表示bi第四行包括一个整数m接下来m行, 对于接下来的第i行:第一个整数ki,表示第i个作物组合中共有ki种作物, 接下来两个整数c1i,c2i,接下来ki个整数,表示该组合中的作物编号。 输出格式 只有一行

搭配飞行员 网络流24题(1/24)

核能气质少年 提交于 2019-11-29 00:48:35
搭配飞行员 题面: 飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾驶员。由于种种原因,例如相互配合的问题,有些驾驶员不能在同一架飞机上飞行,问如何搭配驾驶员才能使出航的飞机最多。 因为驾驶工作分工严格,两个正驾驶员或两个副驾驶员都不能同机飞行。 2<=n<=100 思路: 二分图最大匹配,二分图上跑一下最大流即可 # include <bits/stdc++.h> # define INF 0x3f3f3f3f using namespace std ; const int N = 10005 ; int n , m , ss , tt ; int dis [ N ] ; int cur [ N ] ; queue < int > q ; struct Edge { int to ; int value ; int next ; } e [ N * 4 ] ; int head [ N ] , cnt = - 1 ; void add ( int from , int to , int value ) { cnt ++ ; e [ cnt ] . to = to ; e [ cnt ] . value = value ; e [ cnt ] . next = head [ from ] ; head [ from ] =