首页 > 代码库 > BZOJ 1391: [Ceoi2008]order

BZOJ 1391: [Ceoi2008]order

Description

有一些任务,需要用到一些机器,可以买可以租,问最大获利.

Solution

网络流.

最大权闭合子图模型.

建图很简单就是S->机器,机器->任务,任务->T.

如果没有租用的话,中间的是INF,不会割掉,加上租用就把容量变成租用的价格即可.

这样求出来的割就是最小损失了,用总数减去即可.

Code

/**************************************************************    Problem: 1391    User: BeiYu    Language: C++    Result: Accepted    Time:3864 ms    Memory:55972 kb****************************************************************/ #include <bits/stdc++.h>using namespace std; #define debug(a) cout<<#a<<"="<<a<<" "const int INF = 0x3fffffff;const int N = 3650;const int M = 3000500; inline int in(int x=0,char ch=getchar()) { while(ch>‘9‘ || ch<‘0‘) ch=getchar();    while(ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();return x; } int n,m;int val[N],ned[N],c[N]; struct NetWork {    vector< int > g[N];    struct Edge { int fr,to,fl; }edge[M];    int s,t,cnte,flow,tot;    int cur[N],d[N],p[N];         void AddEdge(int fr,int to,int fl) {        g[fr].push_back(cnte),edge[cnte++]=(Edge){ fr,to,fl };        g[to].push_back(cnte),edge[cnte++]=(Edge){ to,fr,0 };    }    void Build() {        n=in(),m=in();        s=0,t=2*m+n+6;        for(int i=1,x;i<=n;i++) {            for(x=in(),tot+=x,AddEdge(i,t,x),x=in();x--;) {                int idx=in(),cost=in();                AddEdge(n+idx,i,cost);            }        }        for(int i=1;i<=m;i++) {            c[i]=in();            int x=n+i;            AddEdge(s,x,c[i]);        }//      for(int i=1;i<=m;i++) cout<<c1[i]<<" "<<c2[i]<<endl;    }    int BFS() {        queue< int > q;        memset(d,0xff,sizeof(d));        q.push(s),d[s]=1;        for(int x;!q.empty();) {            x=q.front(),q.pop();            for(int i=0,lm=g[x].size(),v;i<lm;i++) if(edge[g[x][i]].fl && d[(v=edge[g[x][i]].to)]==-1) {                d[v]=d[x]+1,q.push(v);            }        }return d[t]!=-1;    }    void Dinic() {//      debug(s),debug(t)<<endl;        for(int u,k;BFS();) {//          cout<<"qwq"<<endl;debug(flow)<<endl;            for(memset(cur,0,sizeof(cur)),u=s,k=0;;) {                if(u==t) {                    int mine=0,minf=INF;                    for(int i=0;i<k;i++) if(edge[p[i]].fl<minf) minf=edge[p[i]].fl,mine=i;                    for(int i=0;i<k;i++) edge[p[i]].fl-=minf,edge[p[i]^1].fl+=minf;//                  for(int i=0;i<k;i++) cout<<edge[p[i]].fr<<"-->";cout<<endl;//                  debug(minf)<<endl;                    k=mine,flow+=minf,u=edge[p[mine]].fr;                }                for(int &i=cur[u],lm=g[u].size(),v;i<lm;i++)                     if(edge[g[u][i]].fl && d[(v=edge[g[u][i]].to)]==d[u]+1) break;                if(cur[u]<(int)g[u].size()) {                    p[k++]=g[u][cur[u]],u=edge[g[u][cur[u]]].to;                } else {                    if(!k) break;                    d[u]=-1,u=edge[p[--k]].fr;                }            }        }    }    int Maxflow() {        flow=0,tot=0;        Build();        Dinic();        return tot-flow;    }}py; int main() {    cout<<py.Maxflow()<<endl;    return 0;}

  

BZOJ 1391: [Ceoi2008]order