[CEOI2008] order
Posted 蒟蒻JHY
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CEOI2008] order相关的知识,希望对你有一定的参考价值。
题目描述
有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成。 现在给出这些参数,求最大利润
输入输出格式
输入格式:
第一行给出 N,M(1<=N<=1200,1<=M<=1200) 下面将有N组数据。
每组数据第一行给出完成这个任务能赚到的钱(其在[1,5000])及有多少道工序
接下来若干行每行两个数,分别描述完成工序所需要的机器编号及租用它的费用(其在[1,20000]) 最后M行,每行给出购买机器的费用(其在[1,20000])
输出格式:
最大利润
输入输出样例
输出样例#1:
50
经典最小割建模。
#include<bits/stdc++.h> #define ll long long #define pb push_back const int maxn=3005; using namespace std; const int inf=1<<30; vector<int> g[maxn]; struct lines{ int to,flow,cap; }l[maxn*1000]; int S,T,t=-1,d[maxn],cur[maxn]; bool v[maxn]; inline void add(int from,int to,int cap){ l[++t]=(lines){to,0,cap},g[from].pb(t); l[++t]=(lines){from,0,0},g[to].pb(t); } inline bool BFS(){ memset(v,0,sizeof(v)); queue<int> q; q.push(S),v[S]=1,d[S]=0; int x; lines e; while(!q.empty()){ x=q.front(),q.pop(); for(int i=g[x].size()-1;i>=0;i--){ e=l[g[x][i]]; if(e.flow<e.cap&&!v[e.to]){ v[e.to]=1,d[e.to]=d[x]+1; q.push(e.to); } } } return v[T]; } int dfs(int x,int A){ if(!A||x==T) return A; int flow=0,f,sz=g[x].size(); for(int &i=cur[x];i<sz;i++){ lines &e=l[g[x][i]]; if(d[e.to]==d[x]+1&&(f=dfs(e.to,min(A,e.cap-e.flow)))){ A-=f,flow+=f; e.flow+=f,l[g[x][i]^1].flow-=f; if(!A) break; } } return flow; } inline int max_flow(){ int an=0; while(BFS()){ memset(cur,0,sizeof(cur)); an+=dfs(S,inf); } return an; } int N,M,ans=0,now,num,K; int main(){ scanf("%d%d",&N,&M),S=0,T=N+M+1; for(int i=1;i<=N;i++){ scanf("%d",&now),ans+=now,add(S,i,now); scanf("%d",&K); while(K--){ scanf("%d%d",&num,&now); add(i,num+N,now); } } for(int i=1;i<=M;i++) scanf("%d",&now),add(i+N,T,now); printf("%d\n",ans-max_flow()); return 0; }
以上是关于[CEOI2008] order的主要内容,如果未能解决你的问题,请参考以下文章