太空飞行计划问题(网络流24题)
Posted sto324
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了太空飞行计划问题(网络流24题)相关的知识,希望对你有一定的参考价值。
题意
有m个实验,n个器材,每个实验做完会得到一些钱,每个实验需要一些器械才能完成,买器材会花钱,器材可以一起用,求最大利益。
n,m<=50
题解
直接写做法了,没做过就想不出来。
源点向实验连边,流量为实验所得的钱,器材想汇点连边,流量为器材花费,实验与相应的器材连边,流量inf。
先假设没花钱做了所有实验得到了所有钱ans(不要face)。
求一遍最小割即可,ans-最小割就是答案。
割掉实验的连边就是不做这个实验,割掉器材的连边就是买这个器材。
输出方案就输出与s连通的即可。(为啥我也不知道)
#include<bits/stdc++.h> using namespace std; const int maxn=105; const int maxm=2705; const int inf=1000005; int n,m,s,t,ans; int val[maxn]; bool flag,get[maxn]; int cnt=1,head[maxn]; struct edge int x,y,next,val; e[maxm<<1]; void add(int x,int y,int val) e[++cnt]=(edge) x,y,head[x],val; head[x]=cnt; template<class T>inline void read(T &x) x=0;char ch=getchar(); while(!isdigit(ch)) ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48);ch=getchar(); flag|=(ch==‘\n‘); int d[maxn]; bool bfs() queue<int> q; memset(d,0,sizeof(d)); q.push(s);d[s]=1; while(!q.empty()) int x=q.front(); q.pop(); for(int i=head[x];i;i=e[i].next) int y=e[i].y; if(e[i].val&&!d[y]) d[y]=d[x]+1; if(y==t) return true; q.push(y); return false; int dfs(int x,int flow) if(x==t) return flow; int rest=flow,k; for(int i=head[x];i;i=e[i].next) int y=e[i].y; if(e[i].val&&d[y]==d[x]+1) k=dfs(y,min(rest,e[i].val)); if(!k) d[y]=0; e[i].val-=k; e[i^1].val+=k; rest-=k; return flow-rest; int dinic() int res=0; while(bfs()) res+=dfs(s,0x3f3f3f); return res; int main() read(m);read(n); s=0;t=n+m+1; for(int i=1;i<=m;i++) int x;read(x); ans+=x; add(s,i,x); add(i,s,0); flag=false; while(!flag) read(x); add(i,x+m,inf); add(x+m,i,0); for(int i=1;i<=n;i++) int x;read(x); add(i+m,t,x); add(t,i+m,0); ans-=dinic(); for(int i=1;i<=m;i++) if(d[i]) printf("%d ",i); putchar(10); for(int i=m+1;i<=n+m;i++) if(d[i]) printf("%d ",i-m); putchar(10); printf("%d",ans);
以上是关于太空飞行计划问题(网络流24题)的主要内容,如果未能解决你的问题,请参考以下文章