zoukankan      html  css  js  c++  java
  • luogu P4177 [CEOI2008]order |最大权闭合子图

    题目描述

    (N) 个工作,(M) 种机器,每种机器可以租或者买。每个工作包括若干道工序,每道工序需要某种机器来完成。

    你需要最大化利益。

    输入格式

    第一行给出 (N,M)

    接下来若干行描述一个工作,对于每个工作,第一行给定 (x_i)(t_i)​,分别表示此工作的收入和工序数。

    后面 (t_i)​ 行,每行两个整数 (a_{ij})​ 和 (b_{ij})​,分别表示此工序需要的机器和此工作租用此机器的费用。

    最后 (M) 行,每行一个正整数表示购买机器的费用 (y_i)

    输出格式

    最大利润


    基本上是最大权闭合子图的模板

    租借操作就把inf改权值

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int N=2505,M=N*N,inf=1<<30;
    int nxt[M],head[N],go[M],edge[M],tot=1;
    inline void add(int u,int v,int w){
        nxt[++tot]=head[u],head[u]=tot,go[tot]=v,edge[tot]=w;
        nxt[++tot]=head[v],head[v]=tot,go[tot]=u,edge[tot]=0;
    }
    int n,m,s,t,maxflow;
    int d[N],now[N];
    bool bfs(){
        queue<int>q;
        memset(d,0,sizeof(d));
        q.push(s); d[s]=1;
        now[s]=head[s];
        while(q.size()){
            int u=q.front(); q.pop();
            for(int i=head[u];i;i=nxt[i]){
                int v=go[i];
                if(edge[i]&&!d[v]){
                    q.push(v);
                    d[v]=d[u]+1;
                    now[v]=head[v];
                    if(v==t)return 1;
                }
            }
        }
        return 0;
    }
    int dinic(int u,int flow){
        if(u==t)return flow;
        for(int &i=now[u];i;i=nxt[i]){
            int v=go[i];
            if(edge[i]&&d[v]==d[u]+1){
                int k=dinic(v,min(flow,edge[i]));
                if(!k)d[v]=0;
                else{
                    edge[i]-=k;
                    edge[i^1]+=k;
                    return k;
                }
            }
        }
        return 0;
    }
    signed main(){
        cin>>n>>m;
        s=0,t=n+m+1;
        int ans=0;
        for(int i=1,x,y,z;i<=n;i++){
            scanf("%d%d",&x,&y);
            add(s,i,x);
            ans+=x;
            while(y--){
                scanf("%d%d",&x,&z);
                add(i,n+x,z);
            }
        }
        for(int i=1,x;i<=m;i++){
            scanf("%d",&x);
            add(n+i,t,x);
        }
        int flow=0;
        while(bfs())
        while(flow=dinic(s,inf))maxflow+=flow;
        cout<<ans-maxflow<<endl;
        
    }
    
  • 相关阅读:
    【原创】Zend Framework快速开发(二)使用命令完成项目
    分析CMMS系统笔记使用js控制快捷键
    学习笔记——php利用@来抑制错误
    WINDOWS + WAMP + Zend Framework 配置
    PHP的$_SERVER变量笔记
    【原创】Zend Framework快速开发(一)zend框架的配置和项目创建(原创)
    带符号的8位2进制数最小值为多少?
    动态规划笔记
    我一直在拖国家的后退
    手机客户端和服务器通信时如何安全高效的进行身份验证
  • 原文地址:https://www.cnblogs.com/naruto-mzx/p/12918736.html
Copyright © 2011-2022 走看看