题目链接

  哈  学会最小费用最大流啦

  思路是这样。

  首先我们有一个贪心策略。如果我们每次找到单位费用和最短的一条增广路,那么显然我们可以把这条路添加到已有的流量里去——不管这条路的流量是多大,反正它能扩大现有流量,而且目前为止它是可以扩大流量的所有路径中单位花费最少的。

  然后我们就把这条路填上。想想看当我们找不到这样一条路的时候会发生什么?

  那就是没有增广路了。恭喜我们获得最小费用最大流。这是为什么呢?

  首先没有任何一条增广路的时候我们肯定获得最大流没错

  然后我们回顾我们扩展的方式。每次我们都选择了一条单位费用和最短的路径,也就是说,我们总是先把便宜的路尽可能利用完了,才去利用那些贵的。鉴于此,我们总是已经把更便宜的填满了,整张图上没有更便宜的路了,才去尝试探索更贵的。

  那么这就是最小费用qwq

  那这个思路怎么实现呢?

  我们可以把边的长度设为单位费用,然后对每个点SPFA。这样SPFA算出来的每个点的距离就是可走增广路中从起点到这个点最少的单位费用和。

  然后SPFA过程中顺便求路径上的流量。顺便记录用了哪些边  最后暴力回跳修改边的信息。

  

#include<cstdio>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<algorithm>
#include<queue>
#define maxn 5050
#define maxm 10050
using namespace std;
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} inline int count(int i){ return i&?i+:i-; } struct Edge{
int from,to,next,val,dis,flow;
}edge[maxm*];
int head[maxn],num;
inline void addedge(int from,int to,int val,int dis){
edge[++num]=(Edge){from,to,head[from],val,dis,};
head[from]=num;
}
inline void add(int from,int to,int val,int dis){
addedge(from,to,val,dis);
addedge(to,from,,-dis);
} bool vis[maxn];
int pre[maxn];
int cost[maxn];
int dst[maxn]; struct Answer{
bool flag;long long flow;long long cost;
}; Answer spfa(int Start,int End){
Answer ans=(Answer){,,};
memset(dst,/,sizeof(dst)); dst[Start]=; cost[Start]=0x7fffffff;
queue<int> f;
f.push(Start);
while(!f.empty()){
int from=f.front(); f.pop();
vis[from]=;
for(int i=head[from];i;i=edge[i].next){
int to=edge[i].to;
if(edge[i].val<=edge[i].flow||dst[to]<=dst[from]+edge[i].dis) continue;
dst[to]=dst[from]+edge[i].dis;
pre[to]=i;
cost[to]=min(cost[from],edge[i].val-edge[i].flow);
if(!vis[to]){
vis[to]=;
f.push(to);
}
}
}
if(dst[End]==dst[]) return ans;
ans.flag=;ans.flow+=cost[End]; ans.cost+=(long long)dst[End]*cost[End];
int now=End;
while(now!=Start){
int ret=pre[now];
edge[ret].flow+=cost[End];
edge[count(ret)].flow-=cost[End];
now=edge[ret].from;
}
return ans;
} long long Flow,Cost; int main(){
int n=read(),m=read(),Start=read(),End=read();
for(int i=;i<=m;++i){
int from=read(),to=read(),val=read(),dis=read();
add(from,to,val,dis);
}
while(){
Answer ans=spfa(Start,End);
if(!ans.flag) break;
if(!ans.flow) break;
Flow+=ans.flow;
Cost+=ans.cost;
}
printf("%lld %lld",Flow,Cost);
return ;
}

【Luogu】P3381最小费用最大流模板(SPFA找增广路)的更多相关文章

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

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

  2. luogu 3376 最小费用最大流 模板

    类似EK算法,只是将bfs改成spfa,求最小花费. 为什么可以呢,加入1-3-7是一条路,求出一个流量为40,那么40*f[1]+40*f[2]+40*f[3],f[1]是第一条路的单位费用,f[2 ...

  3. 【luogu P3381 最小费用最大流】 模板

    题目链接:https://www.luogu.org/problemnew/show/P3381 把bfs变成spfa #include <queue> #include <cstd ...

  4. HDU3376 最小费用最大流 模板2

    Matrix Again Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)To ...

  5. 最大流 && 最小费用最大流模板

    模板从  这里   搬运,链接博客还有很多网络流题集题解参考. 最大流模板 ( 可处理重边 ) ; const int INF = 0x3f3f3f3f; struct Edge { int from ...

  6. 图论算法-最小费用最大流模板【EK;Dinic】

    图论算法-最小费用最大流模板[EK;Dinic] EK模板 const int inf=1000000000; int n,m,s,t; struct node{int v,w,c;}; vector ...

  7. 【网络流#2】hdu 1533 - 最小费用最大流模板题

    最小费用最大流,即MCMF(Minimum Cost Maximum Flow)问题 嗯~第一次写费用流题... 这道就是费用流的模板题,找不到更裸的题了 建图:每个m(Man)作为源点,每个H(Ho ...

  8. poj 2195 最小费用最大流模板

    /*Source Code Problem: 2195 User: HEU_daoguang Memory: 1172K Time: 94MS Language: G++ Result: Accept ...

  9. POJ2135 最小费用最大流模板题

    练练最小费用最大流 此外此题也是一经典图论题 题意:找出两条从s到t的不同的路径,距离最短. 要注意:这里是无向边,要变成两条有向边 #include <cstdio> #include ...

随机推荐

  1. 2017“编程之美”终章:AI之战勇者为王

    编者按:8月15日,第六届微软“编程之美”挑战赛在选手的火热比拼中圆满落下帷幕.“编程之美”挑战赛是由微软主办,面向高校学生开展的大型编程比赛.自2012年起,微软每年都在革新比赛命题.紧跟时代潮流, ...

  2. nmon各配置项含义介绍

    1)nmon各配置项含义介绍

  3. ycsb模板介绍

    #对应的mongodb uri参数等mongodb.url=mongodb://127.0.0.1:27010/test_1 #对应的mongo数据库名称mongodb.database=test_1 ...

  4. 【MYSQL】mysql-5.6.19-win32免安装版本配置方法

    [MYSQL]mysql-5.6.19-win32免安装版本配置方法 1.文件下载网站(http://dev.mysql.com/downloads/): 具体下载地址:http://211.136. ...

  5. Linux配置临时IP地址

    # ifconfig 查看网卡信息,如下图所示: # ifconfig eth0 192.168.0.107 eth0表示第一块网卡,Linux中所有的设配都是文件,所以eth0是第一块网卡的文件名, ...

  6. (转)MyBatis框架的学习(七)——MyBatis逆向工程自动生成代码

    http://blog.csdn.net/yerenyuan_pku/article/details/71909325 什么是逆向工程 MyBatis的一个主要的特点就是需要程序员自己编写sql,那么 ...

  7. vue实现微信分享朋友圈和朋友功能

    vue实现微信分享朋友圈和朋友功能 A-A+ haibao  2018-10-25  11  21  6.2 k  百度已收录  前端开发 温馨提示:本文共3536个字,读完预计9分钟. 这两天在开发 ...

  8. vue的使用-项目总结

    1,这是一个重前端逻辑,轻交互,数据展示的项目,可读性差,2,组件划分的坑,复用过多的坑,复用过多导致要在js手动判断太多东西,不便于可读3,vuex的坑,数据分为后台请求数据的暂存,前端页面逻辑的状 ...

  9. SSI的实例(登录增删改查)

    源码下载:http://download.csdn.net/detail/u011518709/8195143 主要jar包: 配置文件:web.xml <?xml version=" ...

  10. bootstrap 两端对齐的导航

    您可以在屏幕宽度大于768px时,通过在分别使用.nav .nav-tabs或.nav .nav-pills的同时使用class.nav-justified,让标签式或胶囊式导航菜单与父元素等宽,在更 ...