P3381 [模板] 最小费用最大流
EK + dijkstra (2246ms) 开氧气(586ms)
dijkstra的势 可以处理负权 https://www.luogu.org/blog/28007/solution-p3381
#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9; int n, m, s, t, cnt; struct node {
int to, nex, val, cost;
}E[100005];
int head[5005]; void addedge(int x, int y, int va, int cos) {
E[++cnt].to = y; E[cnt].nex = head[x]; head[x] = cnt; E[cnt].val = va; E[cnt].cost = cos;
} struct no1 {
int to, edge;
}pre[5005]; struct no2 {
int d, id;
friend bool operator < (no2 A, no2 B) {
return A.d > B.d;
}
}; int dis[5005];
int h[5005];
bool dij() { for(int i = 1; i <= n; i++) dis[i] = INF;
priority_queue<no2> que; dis[s] = 0;
que.push((no2){0, s}); while(!que.empty()) {
no2 u = que.top();
que.pop();
if(dis[u.id] < u.d) continue; for(int i = head[u.id]; i; i = E[i].nex) {
int v = E[i].to;
if(E[i].val > 0 && dis[v] + h[v] > dis[u.id] + E[i].cost + h[u.id]) {
dis[v] = dis[u.id] + E[i].cost + h[u.id] - h[v];
pre[v].to = u.id;
pre[v].edge = i;
que.push((no2){dis[v], v});
}
}
}
if(dis[t] != INF) return true;
else return false;
} int ans, cos1;
void EK() {
ans = cos1 = 0; while(dij()) {
int mi = INF;
for(int i = t; i != s; i = pre[i].to) {
mi = min(mi, E[pre[i].edge].val);
}
for(int i = t; i != s; i = pre[i].to) {
E[pre[i].edge].val -= mi;
E[pre[i].edge ^ 1].val += mi;
}
for(int i = 1; i <= n; i++) h[i] += dis[i];
ans += mi;
cos1 += mi * h[t];
}
} int main() {
scanf("%d%d%d%d", &n, &m, &s, &t);
cnt = 1; for(int i = 1; i <= m; i++) {
int a, b, c, d;
scanf("%d%d%d%d", &a, &b, &c, &d);
addedge(a, b, c, d);
addedge(b, a, 0, -d);
}
EK();
printf("%d %d\n", ans, cos1);
return 0;
}
EK + spfa (1775ms) 开氧气(1398ms)
#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9; int n, m, s, t, cnt; struct node {
int to, nex, val, cost;
}E[100005];
int head[5005]; void addedge(int x, int y, int va, int cos) {
E[++cnt].to = y; E[cnt].nex = head[x]; head[x] = cnt; E[cnt].val = va; E[cnt].cost = cos;
} struct no1 {
int to, edge;
}pre[5005]; int dis[5005];
int vis[5005]; bool spfa() {
memset(vis, 0, sizeof(vis));
memset(dis, 0x3f, sizeof(dis)); queue<int> que;
que.push(s);
vis[s] = 1;
dis[s] = 0;
while(!que.empty()) {
int u = que.front();
vis[u] = 0;
que.pop(); for(int i = head[u]; i; i = E[i].nex) {
int v = E[i].to;
if(E[i].val > 0 && dis[v] > dis[u] + E[i].cost) {
dis[v] = dis[u] + E[i].cost;
pre[v].to = u;
pre[v].edge = i;
if(!vis[v]) {
vis[v] = 1;
que.push(v);
}
}
}
}
if(dis[t] != 0x3f3f3f3f) return true;
else return false;
} int ans, cos1;
void EK() {
ans = cos1 = 0; while(spfa()) {
int mi = INF;
for(int i = t; i != s; i = pre[i].to) {
mi = min(mi, E[pre[i].edge].val);
}
for(int i = t; i != s; i = pre[i].to) {
E[pre[i].edge].val -= mi;
E[pre[i].edge ^ 1].val += mi;
}
ans += mi;
cos1 += mi * dis[t];
}
} int main() {
scanf("%d%d%d%d", &n, &m, &s, &t);
cnt = 1; for(int i = 1; i <= m; i++) {
int a, b, c, d;
scanf("%d%d%d%d", &a, &b, &c, &d);
addedge(a, b, c, d);
addedge(b, a, 0, -d);
}
EK();
printf("%d %d\n", ans, cos1);
return 0;
}
Dinic多路增广 + 弧优化 + spfa (1744ms)
#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9; int n, m, s, t, cnt;
int maxflow, mincost; struct node {
int to, nex, val, cost;
}E[100005];
int head[5005];
int cur[5005]; void addedge(int x, int y, int va, int cos) {
E[++cnt].to = y; E[cnt].nex = head[x]; head[x] = cnt; E[cnt].val = va; E[cnt].cost = cos;
} struct no1 {
int to, edge;
}pre[5005]; int dis[5005];
int inque[5005];
int vis[5005]; bool spfa() {
for(int i = 1; i <= n; i++) inque[i] = 0, dis[i] = 0x3f3f3f3f, cur[i] = head[i], vis[i] = 0; queue<int> que;
que.push(s);
inque[s] = 1;
dis[s] = 0;
while(!que.empty()) {
int u = que.front();
inque[u] = 0;
que.pop(); for(int i = head[u]; i; i = E[i].nex) {
int v = E[i].to;
if(E[i].val > 0 && dis[v] > dis[u] + E[i].cost) {
dis[v] = dis[u] + E[i].cost;
pre[v].to = u;
pre[v].edge = i;
if(!inque[v]) {
inque[v] = 1;
que.push(v);
}
}
}
}
if(dis[t] != 0x3f3f3f3f) return true;
else return false;
} int dfs(int x, int flow) {
if(x == t) {
vis[x] = 1;
maxflow += flow;
return flow;
} vis[x] = 1;
int used = 0;
int rflow = 0;
for(int i = cur[x]; i; i = E[i].nex) {
cur[x] = i;
int v = E[i].to;
if(E[i].val > 0 && dis[v] == dis[x] + E[i].cost && (!vis[v] || v == t)) {
if(rflow = dfs(v, min(flow - used, E[i].val))) {
used += rflow;
E[i].val -= rflow;
E[i ^ 1].val += rflow;
mincost += E[i].cost * rflow;
if(used == flow) break;
}
}
}
return used;
} void dinic() {
maxflow = mincost = 0;
while(spfa()) {
vis[t] = 1;
while(vis[t]) {
memset(vis, 0, sizeof(vis));
dfs(s, INF);
}
}
} int main() {
scanf("%d%d%d%d", &n, &m, &s, &t);
cnt = 1; for(int i = 1; i <= m; i++) {
int a, b, c, d;
scanf("%d%d%d%d", &a, &b, &c, &d);
addedge(a, b, c, d);
addedge(b, a, 0, -d);
}
dinic();
printf("%d %d\n", maxflow, mincost);
return 0;
}
P3381 [模板] 最小费用最大流的更多相关文章
- 【洛谷 p3381】模板-最小费用最大流(图论)
题目:给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 解法:在Dinic的基础下做spfa算法. 1 #include<cst ...
- 洛谷P3381 (最小费用最大流模板)
记得把数组开大一点,不然就RE了... 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define int long long 4 ...
- 洛谷.3381.[模板]最小费用最大流(zkw)
题目链接 Update:我好像刚知道多路增广就是zkw费用流.. //1314ms 2.66MB 本题优化明显 #include <queue> #include <cstdio&g ...
- P3381 【模板】最小费用最大流
P3381 [模板]最小费用最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行 ...
- 洛谷P3381 最小费用最大流模板
https://www.luogu.org/problem/P3381 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用 ...
- 经典网络流题目模板(P3376 + P2756 + P3381 : 最大流 + 二分图匹配 + 最小费用最大流)
题目来源 P3376 [模板]网络最大流 P2756 飞行员配对方案问题 P3381 [模板]最小费用最大流 最大流 最大流问题是网络流的经典类型之一,用处广泛,个人认为网络流问题最具特点的操作就是建 ...
- P3381 【模板】最小费用最大流(MCMF)
P3381 [模板]最小费用最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入格式 第一行包含四个正整数N ...
- 洛谷P3381 - 【模板】最小费用最大流
原题链接 题意简述 模板题啦~ 题解 每次都以费用作为边权求一下最短路,然后沿着最短路增广. Code //[模板]最小费用最大流 #include <cstdio> #include & ...
- Luogu P3381 (模板题) 最小费用最大流
<题目链接> 题目大意: 给定一张图,给定条边的容量和单位流量费用,并且给定源点和汇点.问你从源点到汇点的最带流和在流量最大的情况下的最小费用. 解题分析: 最小费用最大流果题. 下面的是 ...
随机推荐
- epoll的陷阱实践
在使用epoll的时候,我们上篇文章epoll的陷阱大体介绍了epoll中会有哪些问题.这篇文章我们就针对必须要了解,也是绕不过去的陷阱进行实验,看看现象是什么,并且如何编写才能达到我们想要的效果. ...
- Flutter 基础组件:按钮
前言 Material组件库中提供了多种按钮组件如RaisedButton.FlatButton.OutlineButton等,它们都是直接或间接对RawMaterialButton组件的包装定制,所 ...
- Docker学习笔记之查看Docker
命令: 使用history命令查看镜像历史 使用cp命令复制容器中的文件到主机 使用commit命令把修改过的容器创建为镜像 使用diff命令检查容器文件的修改 使用inspect命令查看容器/镜像详 ...
- Linux 用户操作之用户管理 (用户增删改操作)
目录 添加用户 删除用户 修改用户 切换用户 配置用户密码 查看配置文件 cat /etc/pwsswd 添加用户 可选项 -c comment 指定一段注释性描述. -d 目录 指定用户主目录,如果 ...
- 【MySQL】CentOS7中使用systemctl工具管理启动和停止MySQL
centos7以前版本,可以使用这个/etc/init.d/mysqld start 来启动mysql 但是centos7之后,通过systemctl start mysqld.service 这个要 ...
- 【Linux】cp命令的各种妙用
CP 功能: 复制文件或目录 说明: cp指令用于复制文件或目录,如同时指定两个以上的文件或目录,且最后的目的地是一个已经存在的目录,则它会把前面指定的所有文件或目录复制到此目录中.若同时指定多个文件 ...
- mongodb简单运用
mongodb NoSQL(Not Only SQL),意思是"不仅仅是 SQL",指的是非关系型数据库,是对不同于传统的关系型数据库的数据库管理系统的统称. NoSQL 用于超大 ...
- E1.获取Elixir/Erlang版本信息
E1.获取Elixir/Erlang版本信息 获取Elixir版本 直接在shel中打开iex (interactive shell),就可以查到具体的版本信息: iex Erlang/OTP 22 ...
- 从零开始学spring源码之xml解析(二):默认标签和自定义标签解析
默认标签: 上一篇说到spring的默认标签和自定义标签,发现这里面东西还蛮多的.决定还是拆开来写.今天就来好好聊聊这两块是怎么玩的,首先我们先看看默认标签: private void parseDe ...
- 获取控制台的错误信息 onerror
js 获取控制台的错误信息 https://www.bbsmax.com/A/Vx5ML2NmJN/ <!DOCTYPE html> <html lang="en" ...