Typesetting math: 100%

[网络流24题] 2. 太空飞行计划问题 解题报告

太空飞行计划问题

题意#

m 组实验, n 个器材,

每个实验需要若干个器材, 可以获得一定收益, 每个器材有一定的费用,

求最大净收益 (总收益 - 总费用), 并输出方案.

思路#

将每个器材连向 S, 边权为器材的费用,

将每个实验连向 T, 边权为实验的收益,

每个器材向需要它的实验连边, 边权为 inf,

跑最小割就行了.


需要注意的是, 最后输出方案, 判断每个器材是否被选中时, 不能单纯地判断 S 连向它的边权是否为 0,

因为就算边权为 0, S 还是能够通过其他路径增广它,

所以应该判断 Dinic 算法最后一次 bfs 时有没有经过它, 如果没有经过, 就表示它被选中了.

代码#

Copy
#include<bits/stdc++.h> #define pb push_back #define sz size using namespace std; const int _=100+7; const int __=20400+7; const int inf=0x3f3f3f3f; int n,m,S,T,d[_],max_flow,ans; int lst[_],nxt[__],to[__],c[__],tot=1; char tools[10000]; queue<int> q; vector<int> nd[_]; void add(int x,int y,int w){ nxt[++tot]=lst[x]; to[tot]=y; c[tot]=w; lst[x]=tot; } void read(){ cin>>m>>n; m+=n; S=m+1; T=m+2; int x; for(int i=n+1;i<=m;i++){ scanf("%d",&x); ans+=x; add(i,T,x); add(T,i,0); memset(tools,0,sizeof tools); cin.getline(tools,10000); int ulen=0,tool; while (sscanf(tools+ulen,"%d",&tool)==1) { if (tool==0) ulen++; else { add(tool,i,inf); add(i,tool,0); nd[i-n].pb(tool); while (tool) { tool/=10; ulen++; } } ulen++; } } for(int i=1;i<=n;i++){ scanf("%d",&x); add(S,i,x); add(i,S,0); } } bool bfs(){ for(int i=1;i<=T;i++) d[i]=0; while(!q.empty()) q.pop(); q.push(S); d[S]=1; while(!q.empty()){ int u=q.front(); q.pop(); for(int i=lst[u];i;i=nxt[i]){ int v=to[i]; if(d[v]||!c[i]) continue; d[v]=d[u]+1; if(v==T) return 1; q.push(v); } } return 0; } int dfs(int u,int flow){ if(u==T) return flow; int rest=flow; for(int i=lst[u];i;i=nxt[i]){ int v=to[i]; if(d[v]!=d[u]+1||!c[i]) continue; int cost=dfs(v,min(rest,c[i])); c[i]-=cost; c[i^1]+=cost; rest-=cost; } return flow-rest; } void Dinic(){ int flow; while(bfs()) do{ flow=dfs(S,inf); max_flow+=flow; }while(flow); ans-=max_flow; } void print(){ for(int u=1;u<=m-n;u++){ bool flag=1; for(int i=0;i<(int)nd[u].sz();i++) if(d[nd[u][i]]){ flag=0; break; } if(flag) printf("%d ",u); } putchar('\n'); for(int i=1;i<=n;i++) if(!d[i]) printf("%d ",i); putchar('\n'); printf("%d\n",ans); } int main(){ //freopen("x.in","r",stdin); read(); Dinic(); print(); return 0; }
posted @   BruceW  阅读(119)  评论(0编辑  收藏  举报
编辑推荐:
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 数据库服务器 SQL Server 版本升级公告
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)
· 程序员常用高效实用工具推荐,办公效率提升利器!
点击右上角即可分享
微信分享提示
CONTENTS