zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    Java泛型 T.class的获取
    Android ant自动打包脚本:自动替换友盟渠道、版本号、包名
    验证:mysql AUTO_INCREMENT 默认值是1
    双重OAuth 2.0架构
    使用coding、daocloud和docker打造markdown纯静态博客
    创业小坑:内网域名 在windows下能nslookup,但ping不通,也无法访问。而在linux下正常。
    freeradius 安装出错的解决办法
    与锤子手机HR的对话——创业没有联合创始人,CTO 等高管会把它当做自己的事业吗?
    LBS数据分析:使用地图展示统计数据——麻点图与麻数图
    PHP极客水平测试——给创业公司用的远程面试题
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6390070.html
Copyright © 2011-2022 走看看