网络流

「网络流 24 题」数字梯形

北城余情 提交于 2020-01-22 00:53:24
直接拆点做,但就是搞不懂为什么wa掉了第一小问.... 不管了 #include<bits/stdc++.h> using namespace std; long long tot=-1,sum=0,h[20005],flow[20005],g[20005],ans=0,dis[20005],ans2=0,inf=9999999; bool vis[20005]; struct node{ long long from,to,next,rest,cost; }e[10000005]; void add(long long x,long long y,long long z,long long hg){ tot++; e[tot].next=h[x]; h[x]=tot; e[tot].cost=hg; e[tot].from=x; e[tot].to=y; e[tot].rest=z; } int bfs(long long s,long long t){ queue<int>q; q.push(s);dis[s]=0;vis[s]=true; while(!q.empty()){ long long u=q.front();q.pop();//vis[u]=false; for(int i=h[u];i!=(-1);i=e[i].next){ if(e[i].rest>0&

网络流(多样的建模)

筅森魡賤 提交于 2020-01-21 14:56:09
yhzq的总结是非常好的: 网络流总结 然而博主也不是一个只会复制链接的人,还是要有一点自己的感悟的 网络流问题最重要的就是建模和模型转换,下面就给出一些 经典模型 一、最大流 多源多汇问题 源有多个,汇也有多个,流可以从任意源流出,最终可以流向任意汇, 总流量等于所有源流出的总流量(所有汇流入的总流量) 解: 加一个超级源点S,和超级汇点T, 从S向每一个源点引一条有向弧,容量为 INF ,每个汇点向T引一条有向弧,容量为 INF 结点容量 每个结点都有一个允许通过的最大流量 解: 把每个结点 分裂成两个 x1,x2,中间连一条弧,容量等于x的 结点容量 无源无汇有容量下界网络的可行流 不仅无源无汇,而且每条流量既有 上界c 又有 下界b ,所有结点都应满足“入流=出流” 解: 由于我们只需要求出可行解即可, 可以增加超级源点 S ,和超级汇点 T , 然后对弧进行改造:首先添加弧 T—>S 并设容量为 无穷大 , 然后把每条下界为b的弧 拆成3条 (如图1),然后合并(如图2) 用改造后的图求最大流即可 当且仅当 所有附加弧满流 的时候原网络有可行流 有容量下界网络的s-t最大/最小流 容量同时有上下界,且有源点和汇点各一个,求s到t的最大最小流 解: 先用上题的解法求出可行流, 用传统的增广路方法 即可得到 s-t最大流 把 t看做源点 , s看做汇点 ,求出的 t-s最大流

『网络流算法及其运用』

雨燕双飞 提交于 2020-01-19 23:44:36
本文将重点从运用角度讲解网络流,不会过多阐述网络流基本理论,只讲必要的理论内容,更详细的理论内容可以参考算法导论。 网络流的定义 一个流网络 \(G=(V,E)\) 为一张满足以下条件的 有向图 : 每一条边有一个非负容量,即对于任意 \(E\) 中的 \((u,v)\) , 有 \(c(u,v)≥0\) 。 如果 \(G\) 中存在边 \((u,v)\) ,那么不存在 \((v,u)\) 。我们将图中不存在的边的容量定为 \(0\) 。 图中含有两个特殊节点:源 \(s\) 与汇 \(t\) 。 一个流 \(f\) 是定义在节点二元组 \((u\in V,v\in V)\) 上的 实数函数 ,满足以下两个个性质: 容量限制 :对于任意 \((u,v)\) ,满足 \(0\leq f(u,v)\leq c(u,v)\) 。 流量守恒 :对于任何非源汇的中间节点 \(u\) ,有 \(\sum_{v\in V}f(v,u)=\sum_{v\in V}f(u,v)\) 一个流 \(f\) 的 流量 \(|f|\) 定义为: \(|f|=\sum_{v\in V}f(s,v)-\sum_{v\in V}f(v,s)\) 。 最大流问题 定义 由于图 \(G\) 中不存在反向边,所以在我们一般只关注流量定义式的前半部分,即: \(|f|=\sum_{v\in V}f(s,v)\) 。

洛谷P1402 酒店之王(网络流)

你离开我真会死。 提交于 2020-01-19 16:16:10
### 洛谷P1402 题目链接 ### 题目大意: 有 n 个人, p 间房间,q 种食物。每个人喜欢一些房间,一些食物,但每间房间、每种食物只能分配给一个人。问最大可以让多少个人满足(当且仅当分配到的房间和食物都是自己喜欢的)。 分析: 1、房间与食物只能被分配一次,被分配后不能再被利用。想到二分图匹配问题。 2、再看题干发现,此题不能直接二分图匹配。因为还需要每个人本身也只能被利用一次。比如某个人喜欢的房间是 1 2 ,食物是 3 4 ,那么即便有 1 - 2 、3 - 4 两种匹配,但也只能满足这一个人,并不是满足了两个人的分配问题。 3、综上,即要保证房间和食物的“流量”最大为1,还需要保证人的“流量”最大为 1 。故可以将房间连接于起点 S ,食物连接于终点 T ,容量为 1 。 按样例来看,图应该为这样: 这样保证了房间和食物只能被用一次,但这建图还是错的。。。因为不能保证 人(点3、点4)的流量最大是 1 。比如: 加了这条红色的边后,点3 这个人的最大流量为 2 (从房间 1 和房间 2 流入。且流出于食物 5 和食物 6 ),与题干不符,所以需要把每个人拆成两点,然后中间连一条边,这样就可以限制人的流入与流出了。 代码如下: #include<iostream> #include<algorithm> #include<cstring> #include

[网络流24题] 16.数字梯形问题 解题报告 (最大费用最大流)

旧巷老猫 提交于 2020-01-17 23:44:58
16.数字梯形问题 题意 有一个有数字组成的梯形, 该梯形有 \(n\) 行, 第一行有 \(m\) 列, 每一行都比前一行多一列. 有 \(m\) 条从梯形顶部到底部的路径, 分别以第一行的 \(m\) 个元素作为起点, 每次可以往左下或右下移动. 分别回答满足以下三个条件时, \(m\) 条路径上数字总和的最大值. \(m\) 条路径互不相交. \(m\) 条路径可以点相交, 不可以边相交. \(m\) 条路径既可以点相交, 也可以边相交. 思路 这一道题其实就是 DAG 不相交路径的各种变式. 第一问, 按照套路, 每个点只能出现一次, 那么就把每个点分为 入点 和 出点 , 入点和出点之间连一条容量为 \(1\) , 代价为 \(0\) 的边, 跑最大费用最大流就行了. 第二问, 本来是不用建入点和出点的, 但我们为了避免重复建图, 可以直接把入点到出点的边容量改为 \(inf\) , 其他的和原来一样. 需要注意的是, 不能修改了边权后直接在残量网络上跑最大流, 因为这时已经找不到增广路了. 第三问, 一开始本来是想 \(dp\) 的....但是给出题人点面子...那么就把除了从源点 \(S\) 练出来的边以外, 所有边的边权都改为 \(inf\) . (当然, 反向边除外). 代码 #include<bits/stdc++.h> using namespace std;

【网络流】[HAOI2010] 订货

♀尐吖头ヾ 提交于 2020-01-17 01:14:38
L i n k Link L i n k l u o g u luogu l u o g u 2517 2517 2 5 1 7 D e s c r i p t i o n Description D e s c r i p t i o n 某公司估计市场在第i个月对某产品的需求量为Ui,已知在第i月该产品的订货单价为di,上个月月底未销完的单位产品要付存贮费用m,假定第一月月初的库存量为零,第n月月底的库存量也为零,问如何安排这n个月订购计划,才能使成本最低?每月月初订购,订购后产品立即到货,进库并供应市场,于当月被售掉则不必付存贮费。假设仓库容量为S。 I n p u t Input I n p u t 第1行:n, m, S (0<=n<=50, 0<=m<=10, 0<=S<=10000) 第2行:U1 , U2 , … , Ui , … , Un (0<=Ui<=10000) 第3行:d1 , d2 , …, di , … , dn (0<=di<=100) O u t p u t Output O u t p u t 只有1行,一个整数,代表最低成本 S a m p l e Sample S a m p l e I n p u t Input I n p u t 3 1 1000 2 4 8 1 2 4 S a m p l e Sample S a m p l e O

【网络流】——搞搞dinic

╄→гoц情女王★ 提交于 2020-01-16 13:59:50
只是搞一搞而已。 https://www.luogu.org/problem/P3376网络流最大流板子。 程序 大 部分参考自 A_Comme_Amour 大大的题解。 Dinic: 1.从s跑一遍bfs来分层,如果能分到t层,请转至2。 2.跑dfs,求出当前的flow,加到答案中,欲知细节请到3。 3.dfs(u,t,lim)表示(当前点,汇点,路上最小弧),首先预判一下两种情况:(1.到汇点了,即u==t 2.最小弧为0,即lim==0,都可以直接return lim)   然后跑dfs:往哪个方向走?(往分层处,即新点深度是旧点+1,并且能走(f=dfs(v,t,min(lim,w)),即找增广路),这时候更新路径:原路-f,反向+f,flow+f,lim-f,判断一下lim如果小于等于0就不用再往下增广了。最后返回flow。 4.最后返回flow的和就好了。 5.可以选择弧优化,一点小细节,具体看程序: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 using namespace std; 6 const int inf=1e9; 7 const int N=1e6+10; 8 int n,m,S,T,cnt=-1,maxflow,head[N],cur[N

网络流——最大流Dinic算法

天涯浪子 提交于 2020-01-16 13:30:15
前言 突然发现到了新的一年什么东西好像就都不会了 凉凉 算法步骤 建残量网络图 在残量网络图上跑增广路 重复1直到没有增广路(注意一个残量网络图要尽量把价值都用完,不然会浪费建图的时间) 代码实现 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<algorithm> #include<queue> #include<set> #include<map> #include<iostream> using namespace std; #define ll long long #define re register #define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout) inline int gi(){ int f=1,sum=0;char ch=getchar(); while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();} return f*sum; } const int N=10010,M

网络流Dinic算法

可紊 提交于 2020-01-16 13:29:44
我的模板 例题: https://vjudge.net/problem/HDU-4280 struct Edge { int lst; int from; int to; int cap; int flow; Edge () { } Edge (int llst, int ffrom, int tto, int ccap, int fflow) : lst(llst), from(from), to(tto), cap(ccap), flow(fflow) { } }; // Dinic 算法有3个重点: // 一个是 层次图 // 一个是 阻塞流 // 一个是 cur优化 // 稠密点的可以再加上 炸点优化 class Dinic { public: Edge edge[maxn*2]; int head[maxn]; int cn, cm, cst, ced; int csz; bool vis[maxn]; int dist[maxn]; // 节点到起点层次距离 int cur[maxn]; void init(int n, int m) { cn = n; cm = m; memset(head, 0, sizeof(head)); csz = 2; // 注意 这儿应该是偶数开始 因为 奇数^1等价于减1 偶数^1等价于加一. // 因为我前向星是以0为结尾的

【网络流】【模板】最小费用最大流

一个人想着一个人 提交于 2020-01-16 13:23:25
L i n k Link L i n k l u o g u luogu l u o g u P 3381 P3381 P 3 3 8 1 D e s c r i p t i o n Description D e s c r i p t i o n 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用。 I n p u t Input I n p u t 第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。 接下来M行每行包含四个正整数ui、vi、wi、fi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi),单位流量的费用为fi。 O u t p u t Output O u t p u t 一行,包含两个整数,依次为最大流量和在最大流量情况下的最小费用。 S a m p l e Sample S a m p l e I n p u t Input I n p u t 4 5 4 3 4 2 30 2 4 3 20 3 2 3 20 1 2 1 30 9 1 3 40 5 S a m p l e Sample S a m p l e O u t p u t Output O u t p u t 50 280 H i n t Hint H i n t