BZOJ_1391_[Ceoi2008]order_maximum weight closed subgraph
Description
There are N jobs and M types of machines, each of which you can rent or buy. Each job includes several processes, and each process requires a certain machine to complete, which you can complete by buying or renting a machine. Now given these parameters, find the maximum profit
Input
The first line gives N, M (1<=N<=1200, 1<=M<=1200) There will be N pieces of data below, and the first line of each piece of data gives the money that can be earned by completing this task (its In [1,5000]) and how many operations there are Next several lines with two numbers in each line describe the machine number required to complete the process and the cost of renting it (it is in [1,20000]) The last M lines, each row gives the cost of buying the machine (which is in [1,20000])
Output
maximum profit
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
There are positive and negative weights, and it is easy to think of the maximum weight closed subgraph.
S with process - profit, process with machine - rent cost, machine with T - purchase cost.
Code:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 2500 #define M 3600050 #define S (n+m+1) #define T (n+m+2) #define inf 100000000 int head[N],to[M],nxt[M],flow[M],cnt=1,dep[N],Q[N],l,r,sum,n,m,cur[N]; inline void add(int u,int v,int f) { to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; flow[cnt]=f; to[++cnt]=u; nxt[cnt]=head[v]; head[v]=cnt; flow[cnt]=0; } bool bfs() { int i; memset(dep,0,sizeof(dep)); l=r=0; Q[r++]=S; dep[S]=1; while(l<r) { int x=Q[l++]; for(i=head[x];i;i=nxt[i]) { if(!dep[to[i]]&&flow[i]) { dep[to[i]]=dep[x]+1; if(to[i]==T) return 1; Q[r++]=to[i]; } } } return 0; } int dfs(int x,int mf) { if(x==T) return mf; int nf=0,i; for(i=cur[x];i;i=nxt[i]) { if(dep[to[i]]==dep[x]+1&&flow[i]) { int tmp=dfs(to[i],min(mf-nf,flow[i])); if(!tmp) dep[to[i]]=0; nf+=tmp; flow[i]-=tmp; if(flow[i]) cur[x]=i; flow[i^1]+=tmp; if(nf==mf) break; } } return nf; } void dinic() { int ans=sum,f,i; while(bfs()) { for(i=1;i<=T;i++) cur[i]=head[i]; while(f=dfs(S,inf)) ans-=f; } printf("%d\n",ans); } int main() { scanf("%d%d",&n,&m); int i,x,y,z,w; for(i=1;i<=n;i++) { scanf("%d%d",&x,&y); add(S,i,x); sum+=x; while(y--) { scanf("%d%d",&z,&w); add(i,z+n,w); } } for(i=1;i<=m;i++) { scanf("%d",&x); add(i+n,T,x); } dinic(); }