zoukankan      html  css  js  c++  java
  • bzoj2039: [2009国家集训队]employ人员雇佣

    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

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

    Sample Input

    3
    3 5 100
    0 6 1
    6 0 2
    1 2 0

    Sample Output

    1
    【数据规模和约定】
    20%的数据中N<=10
    50%的数据中N<=100
    100%的数据中 N<=1000, Ei,j<=maxlongint, Ai<=maxlongint
     
    题解:
    这题没有坑,直接二元组建图
    code:
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #define maxn 1005
     7 #define maxm 6000000
     8 #define inf 4557430888798830399LL
     9 using namespace std;
    10 typedef long long int64;
    11 char ch;
    12 bool ok;
    13 void read(int &x){
    14     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    15     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    16     if (ok) x=-x;
    17 }
    18 void read(int64 &x){
    19     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    20     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    21     if (ok) x=-x;
    22 }
    23 int n;
    24 int64 sum,x;
    25 struct flow{
    26     int s,t,tot,now[maxn],son[maxm],pre[maxm];
    27     int64 val[maxm];
    28     int dis[maxn],head,tail,list[maxn];
    29     bool bo[maxn];
    30     void init(){s=0,t=n+1,tot=1,memset(now,0,sizeof(now));}
    31     void put(int a,int b,int64 c){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c;}
    32     void add(int a,int b,int64 c){put(a,b,c),put(b,a,0);}
    33     bool bfs(){
    34         memset(bo,0,sizeof(bo));
    35         head=0,tail=1,list[1]=s,dis[s]=0,bo[s]=1;
    36         while (head<tail){
    37             int u=list[++head];
    38             for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
    39                 if (val[p]&&!bo[v]) bo[v]=1,dis[v]=dis[u]+1,list[++tail]=v;
    40         }
    41         return bo[t];
    42     }
    43     int64 dfs(int u,int64 rest){
    44         if (u==t) return rest;
    45         int64 ans=0;
    46         for (int p=now[u],v=son[p];p&&rest;p=pre[p],v=son[p])
    47             if (val[p]&&dis[v]==dis[u]+1){
    48                 int64 d=dfs(v,min(rest,val[p]));
    49                 val[p]-=d,val[p^1]+=d,ans+=d,rest-=d;
    50             }
    51         if (!ans) dis[u]=-1;
    52         return ans;
    53     }
    54     int64 dinic(){
    55         int64 ans=0;
    56         while (bfs()) ans+=dfs(s,inf);
    57         return ans;
    58     }
    59 }f;
    60 int main(){
    61     read(n),f.init();
    62     for (int i=1;i<=n;i++) read(x),f.add(f.s,i,x<<1);
    63     for (int i=1;i<=n;i++) for (int j=1;j<=n;j++){
    64         read(x);
    65         if (i>j){
    66             sum+=(x<<1);
    67             f.add(i,j,x<<2),f.add(j,i,x<<2);
    68             f.add(i,f.t,x<<1),f.add(j,f.t,x<<1);
    69         }
    70     }
    71     printf("%lld
    ",sum-(f.dinic()>>1));
    72     return 0;
    73 }
  • 相关阅读:
    vim中自动添加文件的作者、时间信息、版本等
    linux shell ipaddress
    java ant学习
    ganglia rpm安装
    深入分析 Java 中的中文编码问题
    javaIO调优
    超强的vim设置
    linux中core文件的生成和配置
    C和C++ 语言动态内存分配
    Linux的常用命令
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/5146734.html
Copyright © 2011-2022 走看看