BZOJ 1391: [Ceoi2008]order
题目大意:
完成一个任务能获得钱,但是需要租用多个机器或者购买多个机器来完成,当然也可以不完成。
求最大利润。
题解:
最小割,比较显然。
代码:
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,S,T,cnt,last[1205*2],q[1205*2],cur[1205*2],h[1205*2];
struct node{
int to,next,cap;
}e[1205*1205*2];
void add(int a,int b,int c){
e[++cnt].to=b;
e[cnt].cap=c;
e[cnt].next=last[a];
last[a]=cnt;
}
void ADD(int a,int b,int c){
add(a,b,c);
add(b,a,0);
}
int bfs(){
for (int i=1; i<=T; i++) h[i]=-1;
h[S]=0;
int head=0,tail=1;
q[tail]=S;
while (head<tail){
int x=q[++head];
for (int i=last[x]; i; i=e[i].next){
int V=e[i].to;
if (e[i].cap && h[V]==-1){
h[V]=h[x]+1;
q[++tail]=V;
}
}
}
return h[T]!=-1;
}
int dfs(int x,int low){
if (x==T) return low;
int used=0;
for (int i=cur[x]; i; i=e[i].next){
int V=e[i].to;
if (e[i].cap && h[V]==h[x]+1){
int w=dfs(V,min(e[i].cap,low-used));
e[i].cap-=w;
e[i^1].cap+=w;
used+=w;
cur[x]=i;
if (low==used) return low;
}
}
if (!used) h[x]=-1;
return used;
}
int dinic(){
int ans=0;
while (bfs()){
for (int i=1; i<=T; i++) cur[i]=last[i];
ans+=dfs(S,1e9);
}
return ans;
}
int main(){
cnt=1;
scanf("%d%d",&n,&m);
S=n+m+1,T=n+m+2;
int ans=0;
for (int i=1; i<=n; i++){
int x,y;
scanf("%d%d",&x,&y);
ans+=x;
ADD(S,i,x);
for (int j=1; j<=y; j++){
int x,y;
scanf("%d%d",&x,&y);
ADD(i,n+x,y);
}
}
for (int i=1; i<=m; i++){
int x;
scanf("%d",&x);
ADD(n+i,T,x);
}
printf("%d\n",ans-dinic());
return 0;
}

浙公网安备 33010602011771号