P4015 运输问题【zkw费用流】

输入输出样例
2 3
220 280
170 120 210
77 39 105
150 186 122
48500
69140zuixiaofeiyo
说明/提示
1 \leq n, m \leq 1001≤n,m≤100
思路
这题不应该算是个紫题吧。。
没啥坑,也很容易想到最大费用流就是把所有边转换为负边权后的最小费用流
建图也很好想

CODE
#include <bits/stdc++.h>
#define dbg(x) cout << #x << "=" << x << endl using namespace std;
typedef long long LL; template<class T>inline void read(T &res)
{
char c;T flag=;
while((c=getchar())<''||c>'')if(c=='-')flag=-;res=c-'';
while((c=getchar())>=''&&c<='')res=res*+c-'';res*=flag;
} const int MAXN = 2e3 + ;
const int inf = 0x3f3f3f3f; int N, M; namespace zkw{
struct Edge{
int to, val, cost;
Edge *next, *ops;
Edge(int to, int val, int cost, Edge *next): to(to), val(val), cost(cost), next(next){}
}; Edge *head[MAXN << ]; void BuildGraph(int u, int v, int w, int c) {
head[u] = new Edge(v, w, c, head[u]);
head[v] = new Edge(u, , -c, head[v]);
head[u]->ops = head[v]; head[v]->ops = head[u];
} int s, t, ans, res;
int dis[MAXN << ];
bool vis[MAXN << ];
void init() {
memset(dis, 0x3f, sizeof(dis));
memset(vis, false, sizeof(vis));
s = , t = , ans = , res = ;
}
bool Spfa() {
memset(vis, false, sizeof vis);
memset(dis, 0x3f, sizeof dis);
deque<int> q;
q.push_back(s);
vis[s] = true; dis[s] = ;
while (!q.empty()) {
int u = q.front(); q.pop_front(); vis[u] = false;
for (Edge *e = head[u]; e; e = e->next) {
int v = e->to;
if (e->val > && dis[u] + e->cost < dis[v]) {
dis[v] = dis[u] + e->cost;
if (!vis[v]) {
vis[v] = true;
if (!q.empty() && dis[v] < dis[q.front()]) q.push_front(v);
else q.push_back(v);
}
}
}
}
return dis[t] < inf;
} int Dfs(int u, int flow) {
if (u == t) {
vis[u] = true;
res += flow;
return flow;
}
int used = ; vis[u] = true;
for (Edge *e = head[u]; e; e = e->next) {//当前弧就不加了
int v = e->to;
if ((!vis[v] || v == t) && e->val && dis[u] + e->cost == dis[v]) {
int mi = Dfs(v, min(e->val, flow - used));
if (mi) {
e->val -= mi;
e->ops->val += mi;
ans += e->cost * mi;
used += mi;
}
if (used == flow) break;
}
}
return used;
} void Work() {
res = ; ans = ;
while (Spfa()) {
vis[t] = true;
while (vis[t]) {
memset(vis, false, sizeof vis);
Dfs(s, inf);
}
}
}
} namespace zkw2{
struct Edge{
int to, val, cost;
Edge *next, *ops;
Edge(int to, int val, int cost, Edge *next): to(to), val(val), cost(cost), next(next){}
}; Edge *head[MAXN << ]; void BuildGraph(int u, int v, int w, int c) {
head[u] = new Edge(v, w, c, head[u]);
head[v] = new Edge(u, , -c, head[v]);
head[u]->ops = head[v]; head[v]->ops = head[u];
} int s, t, ans, res;
int dis[MAXN << ];
bool vis[MAXN << ];
void init() {
memset(dis, 0x3f, sizeof(dis));
memset(vis, false, sizeof(vis));
s = , t = , ans = , res = ;
}
bool Spfa() {
memset(vis, false, sizeof vis);
memset(dis, 0x3f, sizeof dis);
deque<int> q;
q.push_back(s);
vis[s] = true; dis[s] = ;
while (!q.empty()) {
int u = q.front(); q.pop_front(); vis[u] = false;
for (Edge *e = head[u]; e; e = e->next) {
int v = e->to;
if (e->val > && dis[u] + e->cost < dis[v]) {
dis[v] = dis[u] + e->cost;
if (!vis[v]) {
vis[v] = true;
if (!q.empty() && dis[v] < dis[q.front()]) q.push_front(v);
else q.push_back(v);
}
}
}
}
return dis[t] < inf;
} int Dfs(int u, int flow) {
if (u == t) {
vis[u] = true;
res += flow;
return flow;
}
int used = ; vis[u] = true;
for (Edge *e = head[u]; e; e = e->next) {//当前弧就不加了
int v = e->to;
if ((!vis[v] || v == t) && e->val && dis[u] + e->cost == dis[v]) {
int mi = Dfs(v, min(e->val, flow - used));
if (mi) {
e->val -= mi;
e->ops->val += mi;
ans += e->cost * mi;
used += mi;
}
if (used == flow) break;
}
}
return used;
} void Work() {
res = ; ans = ;
while (Spfa()) {
vis[t] = true;
while (vis[t]) {
memset(vis, false, sizeof vis);
Dfs(s, inf);
}
}
}
} int a[], b[];
int val[][];
int val2[][]; signed main() {
read(M);
read(N);
zkw::init();
zkw :: s = ; zkw :: t = M + N + ;
int s = , t = M + N + ;
for ( int i = ; i <= M; ++i ) {
read(a[i]);
zkw::BuildGraph(s, i, a[i], );
}
for ( int i = ; i <= N; ++i ) {
read(b[i]);
zkw::BuildGraph(i + M, t, b[i], );
}
for ( int i = ; i <= M; ++i ) {
for ( int j = ; j <= N; ++j ) {
read(val[i][j]);
val2[i][j] = -val[i][j];
zkw::BuildGraph(i, j + M, inf, val[i][j]);
}
}
zkw :: Work();
cout << zkw::ans << endl;
zkw2::init();
zkw2 :: s = ; zkw2 :: t = M + N + ;
s = , t = M + N + ;
for ( int i = ; i <= M; ++i ) {
zkw2::BuildGraph(s, i, a[i], );
}
for ( int i = ; i <= N; ++i ) {
zkw2::BuildGraph(i + M, t, b[i], );
}
for ( int i = ; i <= M; ++i ) {
for ( int j = ; j <= N; ++j ) {
zkw2::BuildGraph(i, j + M, inf, val2[i][j]);
//printf("u:%d v:%d val2[i][j]:%d\n",i, j + M, val2[i][j]);
}
}
zkw2::Work();
cout << - zkw2::ans << endl;
return ;
}
P4015 运输问题【zkw费用流】的更多相关文章
- 洛谷P4015 运输问题(费用流)
传送门 源点向仓库连费用$0$,流量为储量的边,商店向汇点连费用$0$,流量为需求的边,然后仓库向商店连流量$inf$,费用对应的边,跑个费用流即可 //minamoto #include<io ...
- zkw费用流+当前弧优化
zkw费用流+当前弧优化 var o,v:..] of boolean; f,s,d,dis:..] of longint; next,p,c,w:..] of longint; i,j,k,l,y, ...
- 学习了ZKW费用流
所谓ZKW费用流,其实就是Dinic. 若干年前有一个人发明了最小增广路算法,每次用BFS找一条增广路,时间O(nm^2) 然后被DinicD飞了:我们为什么不可以在长度不变时多路增广呢?时间O(n^ ...
- zkw费用流
期末结束,竞赛生活继续开始,先怒刷完寒假作业再说 至于期末考试,数学跪惨,各种哦智障错,还有我初中常用的建系大法居然被自己抛至脑后,看来学的还是不扎实,以后数学要老老实实学.物理被永哥黑了两分,然后很 ...
- 【zkw费用流】[网络流24题]餐巾计划问题
题目描述 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f ...
- CSU 1948: 超级管理员(普通费用流&&zkw费用流)
Description 长者对小明施加了膜法,使得小明每天起床就像马丁的早晨一样. 今天小明早上醒来发现自己成了一位仓管员.仓库可以被描述为一个n × m的网格,在每个网格上有几个箱子(可能没有).为 ...
- BZOJ2673 [Wf2011]Chips Challenge 费用流 zkw费用流 网络流
https://darkbzoj.cf/problem/2673 有一个芯片,芯片上有N*N(1≤N≤40)个插槽,可以在里面装零件. 有些插槽不能装零件,有些插槽必须装零件,剩下的插槽随意. 要求装 ...
- 图论-zkw费用流
图论-zkw费用流 模板 这是一个求最小费用最大流的算法,因为发明者是神仙zkw,所以叫zkw费用流(就是zkw线段树那个zkw).有些时候比EK快,有些时候慢一些,没有比普通费用流算法更难,所以学z ...
- zkw费用流 学习笔记
分析 记\(D_i\)为从\(S\)出发到\(i\)的最短路 最短路算法保证, 算法结束时 对于任意存在弧\((i,j)\)满足\(D_i + c_{ij}\ge D_j\) ① 且对于每个 \(j\ ...
随机推荐
- (转)嵌入式linux系统开发过程中遇到的——volatile
原文地址:http://blog.csdn.net/HumorRat/article/details/5631023 对于不同的计算机体系结构,设备可能是端口映射,也可能是内存映射的.如果系统结构支持 ...
- .NET 开发工具盘点和现状
在这里我盘点一下.NET的开发工具:Visual Studio.Jetbrains Rider.Mono Develop.SharpDevelop.QuickSharp.Visual Studio C ...
- 通过js自动判断移动终端设备(ios\android等)
当用户用移动设备扫描一个二维码是,将扫描后的链接链接到一个页面,该页面只包含判断移动终端设备的js,判断好后自动跳转到对应的链接 或下载对应的内容. html代码如下: <script> ...
- hive实践_01
本地一份包含有中文的文本文件在上传到hive前,需要先转化为UTF-8格式,否则会出现乱码.(notepad++ 格式>>>转化UTF-8编码格式) -------------- ...
- Session的常用方法
Session的常用方法 session对象主要用于属性操作和会话管理,常用方法如下: 1.public void setAttribute(String name,String value)设定指定 ...
- Selenium系列(二) - 控制浏览器操作的详细解读
如果你还不想从头学起Selenium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1680176.html 其次,如果你不懂前端基础知识 ...
- session生命周期,与cookie的区别
sessinon在用户访问第一次访问服务器时创建. Session什么时候失效? 1. 服务器会把长时间没有活动的Session从服务器内存中清除,此时Session便失效.Tomcat中Sessio ...
- MySQL----DML(增删改表中数据)
##DML:增删改表中的数据 1.添加数据 *语法: * insert into 表名(列名1,列名2,...列名n) values (值1,值2,...值n); *注意: 1.列名和值要一一对应. ...
- 基于树莓派与YOLOv3模型的人体目标检测小车(一)
项目介绍: 本科毕业选的深度学习的毕设,一开始只是学习了一下YOLOv3模型, 按照作者的指示在官网上下载下来权重,配好环境跑出来Demo,后来想着只是跑模型会不会太单薄,于是想了能不能做出来个比较实 ...
- python逐行读取文本
一.使用open打开文件后一定要记得调用文件对象的close()方法.比如可以用try/finally语句来确保最后能关闭文件. 二.需要导入import os 三.下面是逐行读取文件内容的三种方法: ...