当前位置: 首页 > news >正文

AcWing 2174:[模板] 费用流 ← Dinic / EK + SPFA

【题目来源】
https://www.acwing.com/problem/content/2176/

【题目描述】
给定一个包含 n 个点 m 条边的有向图,并给定每条边的容量和费用,边的容量非负。
图中可能存在重边和自环,保证费用不会存在负环。
求从 S 到 T 的最大流,以及在流量最大时的最小费用。

【输入格式】
第一行包含四个整数 n,m,S,T。
接下来 m 行,每行三个整数 u,v,c,w,表示从点 u 到点 v 存在一条有向边,容量为 c,费用为 w。
点的编号从 1 到 n。

【输出格式】
输出点 S 到点 T 的最大流和流量最大时的最小费用。
如果从点 S 无法到达点 T 则输出 0 0。

【输入样例】
5 5 1 5
1 4 10 5
4 5 5 10
4 2 12 5
2 5 10 15
1 5 10 10​​​​​​​

【输出样例】
20 300

【数据范围】
2≤n≤5000,
1≤m≤50000,
0≤c≤100,
−100≤w≤100
S≠T​​​​​​​

【算法分析】
● 百度百科:SPFA 算法是 Bellman-Ford 算法的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环。SPFA 最坏情况下时间复杂度和朴素 Bellman-Ford 相同,为 O(VE)。--- https://blog.csdn.net/hnjzsyjyj/article/details/138425339

【算法代码:Dinic算法 + SPFA

#include <bits/stdc++.h>
using namespace std;typedef long long LL;const int N=5e3+5,M=1e5+5;
const int INF=0x3f3f3f3f;int h[N],e[M],ne[M],cap[M],val[M],idx;
int fv[N],fe[N]; //fv:前驱点, fe:前驱边
int dis[N]; //源点到各点最小费用
bool st[N]; //SPFA入队标记
int d[N]; //Dinic层次
int cur[N]; //Dinic当前弧优化
int n,m,S,T;void add(int a,int b,int c,int w) {cap[idx]=c,val[idx]=w,e[idx]=b,ne[idx]=h[a],h[a]=idx++;cap[idx]=0,val[idx]=-w,e[idx]=a,ne[idx]=h[b],h[b]=idx++;
}bool spfa() {memset(dis,INF,sizeof dis);memset(st,false,sizeof st);memset(d,0,sizeof d);dis[S]=0,d[S]=1;queue<int> q;q.push(S);st[S]=true;while(!q.empty()) {int u=q.front();q.pop();st[u]=false;for(int i=h[u]; ~i; i=ne[i]) {int v=e[i];if(cap[i]>0 && dis[v]>dis[u]+val[i]) {dis[v]=dis[u]+val[i];d[v]=d[u]+1;fv[v]=u, fe[v]=i;if(!st[v]) {q.push(v);st[v]=true;}}}}return dis[T]!=INF;
}int dfs(int u,int lim) {if(u==T) return lim;int flow=0;for(int i=cur[u]; ~i && flow<lim; i=ne[i]) {cur[u]=i;int v=e[i];if(d[v]==d[u]+1 && cap[i] && dis[v]==dis[u]+val[i]) {int t=dfs(v,min(cap[i],lim-flow));if(!t) d[v]=-1;cap[i]-=t,cap[i^1]+=t,flow+=t;}}return flow;
}pair<LL,LL> min_val_max_flow() {LL flow=0,res=0;while(spfa()) {memcpy(cur,h,sizeof cur);int t;while((t=dfs(S,INF))>0) {flow+=t;res+=t*dis[T];}}return make_pair(flow,res);
}/*pair<LL,LL> min_val_max_flow() {LL flow=0,res=0;while(spfa()) {int minc=INF;for(int v=T; v!=S; v=fv[v]) {minc=min(minc,cap[fe[v]]);}flow+=minc;res+=minc*dis[T];for(int v=T; v!=S; v=fv[v]) {int i=fe[v];cap[i]-=minc;cap[i^1]+=minc;}}return make_pair(flow,res);
}*/int main() {ios::sync_with_stdio(false);cin.tie(0);memset(h,-1,sizeof h);cin>>n>>m>>S>>T;for(int i=0; i<m; i++) {int a,b,c,w;cin>>a>>b>>c>>w;add(a,b,c,w);}pair<LL,LL> ans=min_val_max_flow();cout<<ans.first<<" "<<ans.second<<endl;return 0;
}/*
in:
5 5 1 5
1 4 10 5
4 5 5 10
4 2 12 5
2 5 10 15
1 5 10 10out:
20 300
*/

【算法代码:EK算法 + SPFA

#include <bits/stdc++.h>
using namespace std;typedef long long LL;const int N=5e3+5, M=1e5+5;
const int INF=0x3f3f3f3f;
int h[N],e[M],ne[M],cap[M],val[M],idx;
int fv[N],fe[N]; //fv:前驱点, fe:前驱边
int dis[N];
bool st[N];
int n,m,S,T;void add(int a,int b,int c,int w) {cap[idx]=c,val[idx]=w,e[idx]=b,ne[idx]=h[a],h[a]=idx++;cap[idx]=0,val[idx]=-w,e[idx]=a,ne[idx]=h[b],h[b]=idx++;
}bool spfa() {memset(dis,INF,sizeof dis);memset(st,false,sizeof st);dis[S]=0;queue<int> q;q.push(S);st[S]=true;while(!q.empty()) {int u=q.front();q.pop();st[u]=false;for(int i=h[u]; ~i; i=ne[i]) {int v=e[i];if(cap[i]>0 && dis[v]>dis[u]+val[i]) {dis[v]=dis[u]+val[i];fv[v]=u, fe[v]=i;if(!st[v]) {q.push(v);st[v]=true;}}}}return dis[T]!=INF;
}pair<LL,LL> min_val_max_flow() {LL flow=0,res=0;while(spfa()) {int minc=INF;for(int v=T; v!=S; v=fv[v]) {minc=min(minc,cap[fe[v]]);}flow+=minc;res+=minc*dis[T];for(int v=T; v!=S; v=fv[v]) {int i=fe[v];cap[i]-=minc;cap[i^1]+=minc;}}return make_pair(flow,res);
}int main() {ios::sync_with_stdio(false);cin.tie(0);memset(h,-1,sizeof(h));cin>>n>>m>>S>>T;for(int i=0; i<m; i++) {int a,b,c,w;cin>>a>>b>>c>>w;add(a,b,c,w);}pair<LL,LL> ans=min_val_max_flow();cout<<ans.first<<" "<<ans.second<<endl;return 0;
}/*
in:
5 5 1 5
1 4 10 5
4 5 5 10
4 2 12 5
2 5 10 15
1 5 10 10out:
20 300
*/



【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/161317988
https://blog.csdn.net/hnjzsyjyj/article/details/161545392
https://blog.csdn.net/hnjzsyjyj/article/details/138425339
 

http://www.jsqmd.com/news/925522/

相关文章:

  • 终极指南:如何免费解锁Cursor AI Pro功能并突破使用限制
  • 五分钟入门强化学习PPO(Proximal Policy Optimization)
  • 2026PDF转Word免费方案详细教程:软件网页工具一看就会
  • LeetCode 每日一题笔记 日期:2026.05.31 题目:2126. 摧毁小行星
  • 多张图片转pdf的免费工具推荐?2026图片合并转PDF免费方法汇总 - 科技大爆炸
  • 如何永久备份微信聊天记录:WeChatMsg完整本地化解决方案指南
  • Go 语言反射(Reflection)详解
  • 2026全国制造业AI企业应用十大实战服务商深度评测:为何说“人才孵化”才是AI落地的唯一命门? - 速递信息
  • 2026高精度超声波焊接机:解读行业三大核心趋势 - 速递信息
  • 2026手机照片免费转JPG教程!安卓苹果HEIC转JPG不用软件、在线无水印方法
  • 番茄小说永久保存终极指南:3步构建你的个人数字图书馆
  • Redis 常用操作笔记(Go 开发实战)
  • J-Link/J-Trace调试工具在嵌入式开发中的应用与优化
  • 思源宋体终极指南:5分钟掌握免费开源中文字体完整配置方案
  • 别再用Blender了!用Python这5个库搞定3D建模,从数据处理到打印全流程
  • MD怎么转Word?2026年保姆级教程,3步用小程序秒转
  • 全国十大猎头公司实测排行:核心能力对比解析 - 得赢
  • 长三角淘宝网店运营服务商综合能力排行盘点 - 资讯纵览
  • 苏州卫生间楼顶漏水怎么办?厨房、阳台、外墙漏水本地根治方法+靠谱维修指南 - 吉修匠
  • Winhance中文版:一站式Windows系统优化与配置管理解决方案
  • 终极指南:如何快速破解遗忘的压缩包密码
  • 2026EPS转PDF方法大全!Windows/Mac/在线工具及PS/AI转换教程
  • 别再死记命令了!图解华为交换机MAC地址那些事:老化时间、刷新ARP与端口安全详解
  • Go 语言闭包(Closure)详解
  • 淘宝网店运营服务商排行:知名三家机构实力解析 - 速递信息
  • 2026苏州防水哪家好 本地正规补漏公司口碑排名避坑指南 - 吉修匠
  • 2026年全国制造业AI应用实战服务商优选榜单与采购推荐指南 - 速递信息
  • Python集成测试:验证系统协同工作
  • ESP32显示驱动终极指南:打造高效嵌入式图形界面
  • Go 语言匿名函数详解