P3381 【模板】最小费用最大流

题目描述

如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用。

输入输出格式

输入格式:

第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。

接下来M行每行包含四个正整数ui、vi、wi、fi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi),单位流量的费用为fi。

输出格式:

一行,包含两个整数,依次为最大流量和在最大流量情况下的最小费用。

输入输出样例

输入样例#1:

4 5 4 3
4 2 30 2
4 3 20 3
2 3 20 1
2 1 30 9
1 3 40 5
输出样例#1:

50 280

说明

时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=10,M<=10

对于70%的数据:N<=1000,M<=1000

对于100%的数据:N<=5000,M<=50000

样例说明:

如图,最优方案如下:

第一条流为4-->3,流量为20,费用为3*20=60。

第二条流为4-->2-->3,流量为20,费用为(2+1)*20=60。

第三条流为4-->2-->1-->3,流量为10,费用为(2+9+5)*10=160。

故最大流量为50,在此状况下最小费用为60+60+160=280。

故输出50 280。

90分的MCMF(dijkstra被卡常数了)

#include<cstdio>
#include<cstring>
#include<queue>
#define pir pair<int,int>
#define inf 0x33333333
using namespace std;
const int N=1e4+;
const int M=1e5+;
struct node{
int v,next,cap,cost;
node(int v=,int next=,int cap=,int cost=):v(v),next(next),cap(cap),cost(cost){}
}e[M<<];int tot=;
int n,m,S,T,head[N],pv[N],pe[N],dis[N],h[N];
bool vis[N];
void add(int x,int y,int cap,int cost){
e[++tot]=node(y,head[x],cap,cost);
head[x]=tot;
}
pir MCMF(){
int flow=,cost=;
while(){
memset(dis,0x33,sizeof dis);
priority_queue<pir,vector<pir>,greater<pir> >q;
q.push(make_pair(dis[S]=,S));
while(!q.empty()){
pir t=q.top();q.pop();
int x=t.second;
if(t.first!=dis[x]) continue;
if(x==T) break;
for(int i=head[x];i;i=e[i].next){
int v=e[i].v,newcost=e[i].cost+h[x]-h[v];
if(e[i].cap>&&dis[v]>dis[x]+newcost){
dis[v]=dis[x]+newcost;
q.push(make_pair(dis[v],v));
pv[v]=x;pe[v]=i;
}
}
}
if(dis[T]==inf) break;
for(int i=;i<=n;i++) h[i]=min(h[i]+dis[i],inf);
int newflow=inf;
for(int i=T;i!=S;i=pv[i]){
newflow=min(newflow,e[pe[i]].cap);
}
flow+=newflow;
cost+=newflow*h[T];
for(int i=T;i!=S;i=pv[i]){
e[pe[i]].cap-=newflow;
e[pe[i]^].cap+=newflow;
}
}
return make_pair(flow,cost);
}
int main(){
scanf("%d%d%d%d",&n,&m,&S,&T);
for(int i=,x,y,z,w;i<=m;i++) scanf("%d%d%d%d",&x,&y,&z,&w),add(x,y,z,w),add(y,x,,-w);
pir ans=MCMF();
printf("%d %d",ans.first,ans.second);
return ;
}

100分(改成spfa就过了)

/*
以费用作为权值,求出最小费用链,然后在这条链上求得一个最小流量,直到找不到费用链。求最小费用链也就相当于求src->des的最短路径。
使用spfa+EK算法。得到MCMF算法
*/ #include<cstdio>
#include<cstring>
#include<iostream>
#define inf 0x7fffffff
using namespace std;
const int N=1e4+;
const int M=1e5+;
struct node{
int v,next,cap,cost;
}e[M*];int tot=;
int n,m,S,T,head[N],dis[N],flow[N],pree[N],q[M*];
int Flow,Cost;
bool vis[N];
void add(int x,int y,int a,int b){
e[++tot].v=y;e[tot].cap=a;e[tot].cost=b;e[tot].next=head[x];head[x]=tot;
e[++tot].v=x;e[tot].cap=;e[tot].cost=-b;e[tot].next=head[y];head[y]=tot;
}
bool spfa(){
for(int i=;i<=n;i++) vis[i]=,dis[i]=inf;
int h=,t=;dis[S]=;q[t]=S;flow[S]=inf;pree[S]=;
while(h!=t){
int x=q[++h];vis[x]=;
for(int i=head[x];i;i=e[i].next){
int v=e[i].v;
if(e[i].cap&&dis[v]>dis[x]+e[i].cost){
dis[v]=dis[x]+e[i].cost;
pree[v]=i;
flow[v]=min(flow[x],e[i].cap);
if(!vis[v]){
vis[v]=;
q[++t]=v;
}
}
}
}
return dis[T]<inf;
}
void agument(){
for(int i=T;i!=S;i=e[pree[i]^].v){
e[pree[i]].cap-=flow[T];
e[pree[i]^].cap+=flow[T];
}
Flow+=flow[T];
Cost+=flow[T]*dis[T];
}
void MCMF(){
while(spfa()) agument();
}
int main(){
scanf("%d%d%d%d",&n,&m,&S,&T);
for(int i=,x,y,z,w;i<=m;i++) scanf("%d%d%d%d",&x,&y,&z,&w),add(x,y,z,w);
MCMF();
printf("%d %d\n",Flow,Cost);
return ;
}

P3381 【模板】最小费用最大流的更多相关文章

  1. P3381 [模板] 最小费用最大流

    EK  + dijkstra (2246ms) 开氧气(586ms) dijkstra的势 可以处理负权 https://www.luogu.org/blog/28007/solution-p3381 ...

  2. 【洛谷 p3381】模板-最小费用最大流(图论)

    题目:给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 解法:在Dinic的基础下做spfa算法. 1 #include<cst ...

  3. 洛谷P3381 (最小费用最大流模板)

    记得把数组开大一点,不然就RE了... 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define int long long 4 ...

  4. 洛谷.3381.[模板]最小费用最大流(zkw)

    题目链接 Update:我好像刚知道多路增广就是zkw费用流.. //1314ms 2.66MB 本题优化明显 #include <queue> #include <cstdio&g ...

  5. 洛谷P3381 最小费用最大流模板

    https://www.luogu.org/problem/P3381 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用 ...

  6. 经典网络流题目模板(P3376 + P2756 + P3381 : 最大流 + 二分图匹配 + 最小费用最大流)

    题目来源 P3376 [模板]网络最大流 P2756 飞行员配对方案问题 P3381 [模板]最小费用最大流 最大流 最大流问题是网络流的经典类型之一,用处广泛,个人认为网络流问题最具特点的操作就是建 ...

  7. P3381 【模板】最小费用最大流(MCMF)

    P3381 [模板]最小费用最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入格式 第一行包含四个正整数N ...

  8. 洛谷P3381 - 【模板】最小费用最大流

    原题链接 题意简述 模板题啦~ 题解 每次都以费用作为边权求一下最短路,然后沿着最短路增广. Code //[模板]最小费用最大流 #include <cstdio> #include & ...

  9. Luogu P3381 (模板题) 最小费用最大流

    <题目链接> 题目大意: 给定一张图,给定条边的容量和单位流量费用,并且给定源点和汇点.问你从源点到汇点的最带流和在流量最大的情况下的最小费用. 解题分析: 最小费用最大流果题. 下面的是 ...

随机推荐

  1. 在iOS开发过程中你遇到这个问题了么?

    1.问题:加载UIWebView底部有黑色边框问题. 设置UIWebView opaque为NO,然后设置其背景色为clearColor. 2.问题:iPhone真机输出[UIScreen mainS ...

  2. 自定义Dialog宽度占满屏幕

    一.自定义Dialog继承Dialog public class MyDialog extends Dialog { 二.为Dialog设置样式 在style中建立新样式继承 @android:sty ...

  3. webpack入门和实战(一):webpack配置及技巧

    一.全面理解webpack 1.什么是 webpack? webpack是近期最火的一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX).coffee.样式(含less/sass).图片等都 ...

  4. CocoaPods安装以及相关问题解决

    Mac OS X上安装 Ruby环境 安装RVM $ curl -L https://get.rvm.io | bash -s stable 关闭终端,新开另外一个终端(新打开的终端会自动载入RVM环 ...

  5. JMS(Java消息服务)入门教程

    什么是Java消息服务 Java消息服务指的是两个应用程序之间进行异步通信的API,它为标准消息协议和消息服务提供了一组通用接口,包括创建.发送.读取消息等,用于支持JAVA应用程序开发.在J2EE中 ...

  6. Sqlite学习笔记(二)&&性能测试

    测试目标 获取SQlite的常规性能指标 测试环境 CPU:8核,Intel(R) Xeon(R) CPU E5-2430 0 @ 2.20GHz 内存:16G 磁盘:SSD Linux 2.6.32 ...

  7. MySQL online ddl原理

    背景 dba的日常工作肯定有一项是ddl变更,ddl变更会锁表,这个可以说是dba心中永远的痛,特别是执行ddl变更,导致库上大量线程处于“Waiting for meta data lock”状态的 ...

  8. 记录一些在用wcf的过程中走过的泥巴路 【第一篇】

    自从转移战场之后,比以前忙多了,博客也没能及时跟上,原本准备继续mvc系列,但是在那边技术比较陈旧还没能用得上,话说有3年没接触这玩意了,东西也 都忘了差不多了,既然再次接触,我也就继续温习温习,记录 ...

  9. 编写一个Java应用程序,该应用程序包括2个类:Print类和主类E。Print 类里有一个方法output()功能是输出100 ~ 999之间的所有水仙花数(各位数字的 立方和等于这个三位数本身,如: 371 = 33 + 73 + 13。)在主类E的main方法中来 测试类Print

    package zuoye; public class print { void output() { System.out.println("100-999之间的水仙花数是:") ...

  10. 已知2个一维数组:a[]={3,4,5,6,7},b[]={1,2,3,4,5,6,7};把数组a与数组b ,对应的元素乘积再赋值给数组b,如:b[2]=a[2]*b[2];最后输出数组b的元素。

    int[]a={3,4,5,6,7}; int[]b={1,2,3,4,5,6,7}; int[] arry=new int[7]; System.out.print("数组b[]={&qu ...