洛谷 P3381 【【模板】最小费用最大流】
题目描述
如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用。
输入
第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。
接下来M行每行包含四个正整数ui、vi、wi、fi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi),单位流量的费用为fi。
输出
一行,包含两个整数,依次为最大流量和在最大流量情况下的最小费用。
样例输入
4 5 4 3
4 2 30 2
4 3 20 3
2 3 20 1
2 1 30 9
1 3 40 5样例输出
50 280
555555本蒟蒻还不会zkw费用流,就先贴Edmond_Karp+SPFA和Primal_Dual的代码吧。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std; struct edge {
int to,cap,cost,rev;
}; typedef pair<int,int> P;
const int maxn=, maxm=, INF=0x7F7F7F7F;
int n,m;
vector <edge> G[maxn+]; edge make_edge(int to, int cap, int cost, int rev) {
edge x;
x.to=to, x.cap=cap, x.cost=cost, x.rev=rev;
return x;
} void add_edge(int from, int to, int cap, int cost) {
G[from].push_back(make_edge(to,cap,cost,G[to].size()));
G[to].push_back(make_edge(from,,-cost,G[from].size()-));
} void init(int &s, int &t) {
scanf("%d%d%d%d",&n,&m,&s,&t);
for (int i=; i<=m; i++) {
int u,v,w,f;
scanf("%d%d%d%d",&u,&v,&w,&f);
add_edge(u,v,w,f);
}
} namespace EK_SPFA {
int dis[maxn+];
int prev[maxn+];
int pree[maxn+]; void bfs(int s) {
bool mark[maxn+];
memset(dis,0x7F,sizeof(dis));
memset(prev,-,sizeof(prev));
memset(pree,-,sizeof(pree));
memset(mark,,sizeof(mark));
queue <int> q;
dis[s]=;
q.push(s);
while (!q.empty()) {
int x=q.front();
q.pop();
mark[x]=false;
for (int i=; i<G[x].size(); i++) {
edge &e=G[x][i];
if (e.cap>&&dis[x]+e.cost<dis[e.to]) {
dis[e.to]=dis[x]+e.cost;
prev[e.to]=x;
pree[e.to]=i;
if (!mark[e.to]) {
mark[e.to]=true;
q.push(e.to);
}
}
}
}
} P min_cost_max_flow(int s, int t) {
int flow=, cost=;
for(;;) {
bfs(s);
if (dis[t]==INF)
return make_pair(flow,cost);
int d=INF;
for (int i=t; prev[i]!=-; i=prev[i])
d=min(d,G[prev[i]][pree[i]].cap);
flow+=d;
cost+=d*dis[t];
for (int i=t; prev[i]!=-; i=prev[i]) {
edge &e=G[prev[i]][pree[i]];
e.cap-=d;
G[e.to][e.rev].cap+=d;
}
}
}
} namespace Primal_Dual {
int dis[maxn+];
int h[maxn+];
int prev[maxn+];
int pree[maxn+]; void bfs(int s) {
priority_queue <P, vector<P>, greater<P> > q;
bool vis[maxn+];
memset(vis,,sizeof(vis));
memset(dis,0x7F,sizeof(dis));
memset(prev,-,sizeof(prev));
memset(pree,-,sizeof(pree));
dis[s]=;
q.push(make_pair(,s));
while (!q.empty()) {
int val=q.top().first, x=q.top().second;
q.pop();
if (vis[x]) continue;
vis[x]=true;
for (int i=; i<G[x].size(); i++) {
edge &e=G[x][i];
if (e.cap>&&dis[x]+e.cost+h[x]-h[e.to]<dis[e.to]&&!vis[e.to]) {
dis[e.to]=dis[x]+e.cost+h[x]-h[e.to];
prev[e.to]=x;
pree[e.to]=i;
q.push(make_pair(dis[e.to],e.to));
}
}
}
} P min_cost_max_flow(int s, int t) {
int flow=, cost=;
memset(h,,sizeof(h));
for(;;) {
bfs(s);
if (dis[t]==INF)
return make_pair(flow,cost);
for (int i=; i<=n; i++)
h[i]+=dis[i];
int d=INF;
for (int i=t; prev[i]!=-; i=prev[i])
d=min(d,G[prev[i]][pree[i]].cap);
flow+=d;
cost+=d*h[t];
for (int i=t; prev[i]!=-; i=prev[i]) {
edge &e=G[prev[i]][pree[i]];
e.cap-=d;
G[e.to][e.rev].cap+=d;
}
}
}
} int main() {
int s,t;
init(s,t);
P ans=Primal_Dual::min_cost_max_flow(s,t);
printf("%d %d\n",ans.first,ans.second);
return ;
}
洛谷 P3381 【【模板】最小费用最大流】的更多相关文章
- 洛谷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 [模板] 最小费用最大流
EK + dijkstra (2246ms) 开氧气(586ms) dijkstra的势 可以处理负权 https://www.luogu.org/blog/28007/solution-p3381 ...
- 【洛谷 p3381】模板-最小费用最大流(图论)
题目:给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 解法:在Dinic的基础下做spfa算法. 1 #include<cst ...
- 洛谷.4897.[模板]最小割树(Dinic)
题目链接 最小割树模板.具体见:https://www.cnblogs.com/SovietPower/p/9734013.html. ISAP不知为啥T成0分了.. Dinic: //1566ms ...
- 网络流_spfa最小费用最大流
最大流: 不断搜索增广路,寻找最小的容量-流量,得到最大流量,但最大流量在有花费时不一定是最小花费. 最小费用最大流 算法思想: 采用贪心的思想,每次找到一条从源点到达汇点的花费最小的路径,增加流量, ...
- 洛谷P3381 最小费用最大流模板
https://www.luogu.org/problem/P3381 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用 ...
- 洛谷P3381 - 【模板】最小费用最大流
原题链接 题意简述 模板题啦~ 题解 每次都以费用作为边权求一下最短路,然后沿着最短路增广. Code //[模板]最小费用最大流 #include <cstdio> #include & ...
- P3381 【模板】最小费用最大流
P3381 [模板]最小费用最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行 ...
- 经典网络流题目模板(P3376 + P2756 + P3381 : 最大流 + 二分图匹配 + 最小费用最大流)
题目来源 P3376 [模板]网络最大流 P2756 飞行员配对方案问题 P3381 [模板]最小费用最大流 最大流 最大流问题是网络流的经典类型之一,用处广泛,个人认为网络流问题最具特点的操作就是建 ...
随机推荐
- 移动iptv安装三方软件
1.思路: 分为硬件和软件. a.硬件是ttl直接上串口,弄得比较复杂,且容易损坏盒子,先不考虑 b.软件:抓包获取iptv的请求数据,将移动光猫的iptv出口接到交换机上,电脑和盒子接入到同一个交 ...
- js添加和删除class
原生主要有三种方法: 1.className var DomClass = document.getElementById("id").className; //删除 pat Do ...
- OO第一单元表达式求导作业总结
第一次作业 功能描述: 对输入的表达式进行求导计算和格式正误判断 思路: 一开始的想法是想写一个大正则找到一个通项式,通过这个多项式来判断WRONG FORMAT,结果发现正则写的总是不完善,会漏 ...
- WPF线程中获取控件的值和给控件赋值
WPF中使用线程操作控件,按平常的操作方法操作的话会报异常:调用线程无法访问此对象,因为另一个线程拥有该对象.所以我们要使用Dispatcher类的BeginInvoke()与Invoke()方法.B ...
- 原生js获取 一个dom元素距离页面可视区域的位置值 -- getBoundingClientRect
getBoundingClientRect() 这个方法返回一个矩形对象,包含四个属性:left.top.right和bottom.分别表示元素各边与页面上边和左边的距离. var box=docum ...
- 易爆物D305
分析:典型的并查集,每一个物品合一看成一个独立的顶点,则一个简单化合物就是一条边,如果两个顶点x,y联通则说明有危险,所以可以用一个并查集来维护图的联通分量集合,并查集的详解有一篇写的很易懂的博客并查 ...
- 执行python解释器的两种方式
执行python解释器的两种方式 1.交互式 python是高级语言,是解释型语言,逐行翻译,写一句翻译一句 print ('hello world') 2.命令行式 python和python解释器 ...
- JavaScript--鼠标滚动改变图片大小
鼠标滚动改变图片的大小: 原理:当鼠标滚动时改变了zoom的值: <!DOCTYPE HTML> <html> <head> <title>通过鼠标滚轮 ...
- office 2016 官方原版 (含Visio Project 等全套 )下载地址 (不含破解,非网盘下载)不用登录
原文地址:https://www.heidoc.net/joomla/technology-science/microsoft/8-office-2016-direct-download-links ...
- 修改Vim内注释字体颜色
vim /etc/vimrc 然后按大写 G 到最后一行,插入 hi comment ctermfg=6 wq保存退出 PS:默认的注释颜色是4 然后有0,1,2,3,4,5 ...