题目描述
有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成。 现在给出这些参数,求最大利润
输入输出格式
输入格式:
第一行给出 N,M(1<=N<=1200,1<=M<=1200) 下面将有N组数据。
每组数据第一行给出完成这个任务能赚到的钱(其在[1,5000])及有多少道工序
接下来若干行每行两个数,分别描述完成工序所需要的机器编号及租用它的费用(其在[1,20000]) 最后M行,每行给出购买机器的费用(其在[1,20000])
输出格式:
最大利润
输入输出样例
输入样例#1:
2 3
100 2
1 30
2 20
100 2
1 40
3 80
50
80
110
输出样例#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;
}