BZOJ_1391_[Ceoi2008]order_maximum weight closed subgraph

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

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();
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325043709&siteId=291194637