zoukankan      html  css  js  c++  java
  • BZOJ2039 [2009国家集训队]employ人员雇佣(DInic算法求最大流)

    题意:

    Description

    作为一个富有经营头脑的富翁,小L决定从本国最优秀的经理中雇佣一些来经营自己的公司。这些经理相互之间合作有一个贡献指数,(我们用Ei,j表示i经理对j经理的了解程度),即当经理i和经理j同时被雇佣时,经理i会对经理j做出贡献,使得所赚得的利润增加Ei,j。当然,雇佣每一个经理都需要花费一定的金钱Ai,对于一些经理可能他做出的贡献不值得他的花费,那么作为一个聪明的人,小L当然不会雇佣他。 然而,那些没有被雇佣的人会被竞争对手所雇佣,这个时候那些人会对你雇佣的经理的工作造成影响,使得所赚得的利润减少Ei,j(注意:这里的Ei,j与上面的Ei,j 是同一个)。 作为一个效率优先的人,小L想雇佣一些人使得净利润最大。你可以帮助小L解决这个问题吗?

    Input

    第一行有一个整数N<=1000表示经理的个数 第二行有N个整数Ai表示雇佣每个经理需要花费的金钱 接下来的N行中一行包含N个数,表示Ei,j,即经理i对经理j的了解程度。(输入满足Ei,j=Ej,i)

    Output

    第一行包含一个整数,即所求出的最大值。

    题解:

    源点向每个经理建边,容量为经理的价格。

    经理之间建边,容量为了解程度的两倍

    同时统计所有经理之间了解程度之和。

    这个总和减去全图最大流就是答案

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=4e6;
    const int inf=1e9;
    int head[maxn];
    int tol;
    struct node {
        int u;
        int v;
        int w;
        int next;
    }edge[maxn];
    void addedge (int u,int v,int w) {
        edge[tol].u=u;
        edge[tol].v=v;
        edge[tol].w=w;
        edge[tol].next=head[u];
        head[u]=tol++;
        edge[tol].u=v;
        edge[tol].v=u;
        edge[tol].w=0;
        edge[tol].next=head[v];
        head[v]=tol++;
    }
    
    
    int dep[maxn];
    int inque[maxn];
    int vi;
    int cur[maxn];
    int maxflow=0;
    int s,t;
    bool bfs () {
        for (int i=0;i<=t;i++) 
            cur[i]=head[i],dep[i]=inf,inque[i]=0;
        dep[s]=0;
        queue<int> q;
        q.push(s);
        while (!q.empty()) {
            int u=q.front();
            q.pop();
            inque[u]=0;
            for (int i=head[u];i!=-1;i=edge[i].next) {
                int v=edge[i].v;
                if (dep[v]>dep[u]+1&&edge[i].w) {
                    dep[v]=dep[u]+1;
                    if (inque[v]==0) {
                        q.push(v);
                        inque[v]=1;
                    } 
                }
            }
        }
        if (dep[t]!=inf) return 1;
        return 0;
    }
    int dfs (int u,int flow) {
        int increase=0;
        if (u==t) {
            vi=1;
            maxflow+=flow;
            return flow;
        }
        int used=0;
        for (int i=cur[u];i!=-1;i=edge[i].next) {
            cur[u]=i;
            int v=edge[i].v;
            if (edge[i].w&&dep[v]==dep[u]+1) {
                if (increase=dfs(v,min(flow-used,edge[i].w))) {
                    used+=increase;
                    edge[i].w-=increase;
                    edge[i^1].w+=increase;
                    if (used==flow) break;
                }
            }
        }
        return used;
    }
    int Dinic () {
        while (bfs()) {
            vi=1;
            while (vi==1) {
                vi=0;
                dfs(s,inf);
            }
        } 
        return maxflow;
    }
    int main () {
        int N;
        int ans=0;
        scanf("%d",&N);
        s=0,t=N+1;
        memset(head,-1,sizeof(head));
        for (int i=1;i<=N;i++) {
            int x;
            scanf("%d",&x);
            addedge(s,i,x);
        }
        for (int i=1;i<=N;i++) {
            int sum=0;
            for (int j=1;j<=N;j++) {
                int x;
                scanf("%d",&x);
                ans+=x;
                sum+=x;
                if (i!=j) addedge(i,j,x*2);
            }
            addedge(i,t,sum);
        }
        printf("%d
    ",ans-Dinic());
    } 
  • 相关阅读:
    免费音频录制及处理软件 Audacity
    centos7设置程序开机启动方案
    tomcat开启前或者关闭前执行清理任务 servlet基础知识解决
    BigDecimal比较大小及判0处理
    File文件夹操作创建层级文件夹
    centos7设置activemq开机启动
    tomcat关闭时无法清理资源解决方案
    java数据类型和C++的对应关系 SDK开发
    centos7查询开机启动项及设置服务为开机自启动
    Entity Framework 教程
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12557922.html
Copyright © 2011-2022 走看看