BZOJ1391: [Ceoi2008]order
Description
有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成。 现在给出这些参数,求最大利润
Input
第一行给出 N,M(1<=N<=1200,1<=M<=1200) 下面将有N块数据,每块数据第一行给出完成这个任务能赚到的钱(其在[1,5000])及有多少道工序 接下来若干行每行两个数,分别描述完成工序所需要的机器编号及租用它的费用(其在[1,20000]) 最后M行,每行给出购买机器的费用(其在[1,20000])
Output
最大利润
Sample Input
2 3
100 2
1 30
2 20
100 2
1 40
3 80
50
80
110
100 2
1 30
2 20
100 2
1 40
3 80
50
80
110
Sample Output
50
HINT
最小割裸题。。。
#include<cstdio> #include<cctype> #include<queue> #include<cmath> #include<cstring> #include<algorithm> #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define ren for(int i=first[x];i!=-1;i=next[i]) using namespace std; const int BufferSize=1<<16; char buffer[BufferSize],*head,*tail; inline char Getchar() { if(head==tail) { int l=fread(buffer,1,BufferSize,stdin); tail=(head=buffer)+l; } return *head++; } inline int read() { int x=0,f=1;char c=Getchar(); for(;!isdigit(c);c=Getchar()) if(c=='-') f=-1; for(;isdigit(c);c=Getchar()) x=x*10+c-'0'; return x*f; } const int maxn=3010; const int maxm=3000010; const int inf=1e9; struct ISAP{ struct tedge{int x,y,w,next;}adj[maxm];int ms,fch[maxn]; int d[maxn],s[maxn],cur[maxn],gap[maxn],n,top; void init(int n){ this->n=n;ms=0;top=0; memset(d,-1,sizeof(d)); memset(fch,-1,sizeof(fch)); return; } void AddEdge(int u,int v,int w){ adj[ms]=(tedge){u,v,w,fch[u]};fch[u]=ms++; adj[ms]=(tedge){v,u,0,fch[v]};fch[v]=ms++; return; } void bfs(){ queue<int>Q;Q.push(n);d[n]=0; while(!Q.empty()){ int u=Q.front();Q.pop(); for(int i=fch[u];i!=-1;i=adj[i].next){ int v=adj[i].y; if(d[v]==-1) d[v]=d[u]+1,Q.push(v); } } return; } int solve(int S,int T){ n=T;bfs();int k=S,i,flow=0; for(i=0;i<=n;i++) cur[i]=fch[i],gap[d[i]]++; while(d[S]<n){ if(k==n){ int mi=inf,pos; for(i=0;i<top;i++) if(adj[s[i]].w<mi) mi=adj[s[i]].w,pos=i; for(i=0;i<top;i++) adj[s[i]].w-=mi,adj[s[i]^1].w+=mi; flow+=mi;top=pos;k=adj[s[top]].x; } for(i=cur[k];i!=-1;i=adj[i].next){ int v=adj[i].y; if(adj[i].w&&d[k]==d[v]+1){cur[k]=i;k=v;s[top++]=i;break;} } if(i==-1){ int lim=n; for(i=fch[k];i!=-1;i=adj[i].next){ int v=adj[i].y; if(adj[i].w&&d[v]<lim) lim=d[v],cur[k]=i; } if(--gap[d[k]]==0) break; d[k]=lim+1;gap[d[k]]++; if(k!=S) k=adj[s[--top]].x; } } return flow; } }sol; int c[maxn]; int main() { int n=read(),m=read();int sum=0; sol.init(n+m+2);int S=n+m+1,T=S+1; rep(i,1,n) { sum+=(c[i]=read());int k=read(); sol.AddEdge(S,i,c[i]); while(k--) { int x=read(),v=read(); sol.AddEdge(i,n+x,v); } } rep(i,1,m) sol.AddEdge(i+n,T,read()); printf("%d\n",sum-sol.solve(S,T)); return 0; }