zoukankan      html  css  js  c++  java
  • 【BZOJ2039】【2009国家集训队】人员雇佣 [最小割]

    人员雇佣

    Time Limit: 20 Sec  Memory Limit: 259 MB
    [Submit][Status][Discuss]

    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

    HINT

      20%的数据中 N<=10
      50%的数据中 N<=100
      100%的数据中 N<=1000 , Ei,j<=maxlongint , Ai<=maxlongint

    Main idea

      给定若干关系,选择一个人需要固定的费用,对于i,j,选择了其中一个则损失E[i][j],两个都选了则获得2*E[i][j],问能获得的最大价值。

    Solution

      显然就是一个最小割的模型,我们直接套用论文里面的模型即可。

      针对于这道题,我们对于代价建图,用Ans=总和-最小代价即可。

      对于第i个点,如果选了,会损失a[i],连边(S,i,a[i]):表示选了它之后的代价;如果不选,会损失ΣE[i][j],所以连边(i,T,ΣE[i][j]),表示不选的损失。

      然后对于一对点i,j,连边(i,j,2*E[i][j]),表示如果不选i,选了j的话,本来i中选j的利益得不到,又要损失j对i的影响为E[i][j],一共损失了2*E[i][j]。

      然后求一下最小割即可。

    Code

      1 #include<iostream>    
      2 #include<string>    
      3 #include<algorithm>    
      4 #include<cstdio>    
      5 #include<cstring>    
      6 #include<cstdlib>    
      7 #include<cmath>    
      8 #include<map>  
      9 using namespace std;  
     10  
     11 typedef long long s64;
     12 const int ONE=5000005;
     13 const s64 INF=21474836400000;
     14     
     15 int n,x;
     16 s64 res;
     17 int tou,wei,S,T;
     18 int Dep[ONE],q[1000001],E[ONE];
     19 int next[ONE],first[ONE],go[ONE],tot;
     20 s64 w[ONE];
     21 s64 Ans;
     22  
     23 int get()
     24 {    
     25         int res=1,Q=1;char c;    
     26         while( (c=getchar())<48 || c>57 ) 
     27         if(c=='-')Q=-1; 
     28         res=c-48;     
     29         while( (c=getchar())>=48 && c<=57 )    
     30         res=res*10+c-48;    
     31         return res*Q;    
     32 }
     33   
     34 int Add(int u,int v,s64 z)
     35 {
     36         next[++tot]=first[u];   first[u]=tot;   go[tot]=v;  w[tot]=z;
     37         next[++tot]=first[v];   first[v]=tot;   go[tot]=u;  w[tot]=0;
     38 }
     39     
     40 int Bfs()
     41 {
     42         memset(Dep,0,sizeof(Dep));
     43         tou=0;  wei=1;
     44         q[1]=S; Dep[S]=1;
     45         for(int i=S;i<=T;i++) E[i]=first[i];
     46         while(tou<wei)
     47         {
     48             int u=q[++tou];
     49             for(int e=first[u];e;e=next[e])
     50             {
     51                 int v=go[e];
     52                 if(Dep[v] || !w[e]) continue;
     53                 Dep[v]=Dep[u]+1;
     54                 q[++wei]=v;
     55             }
     56         }
     57         return (Dep[T]>0);
     58 }
     59  
     60 s64 Dfs(int u,s64 Limit)
     61 {
     62         if(u==T || !Limit) return Limit;
     63         s64 from=0,f;
     64         for(int &e=E[u];e;e=next[e])
     65         {
     66             int v=go[e];
     67             if(Dep[v]!=Dep[u]+1 || !w[e]) continue;
     68             f=Dfs(v,min(Limit,w[e]));
     69             w[e]-=f;
     70             w[((e-1)^1)+1]+=f;
     71             Limit-=f;
     72             from+=f;
     73             if(!Limit) break;
     74         }
     75         return from; 
     76 }
     77  
     78 int main()  
     79 {
     80         n=get();
     81         S=0;    T=n+1;
     82         for(int i=1;i<=n;i++)
     83         {
     84             x=get();
     85             Add(S,i,x);
     86         }
     87          
     88         for(int i=1;i<=n;i++)
     89         {
     90             res=0;
     91             for(int j=1;j<=n;j++)
     92             {
     93                 x=get();
     94                 res+=x; Ans+=x;
     95                 Add(i,j,2*x);
     96             }
     97             Add(i,T,res);
     98         }
     99          
    100         while(Bfs()) Ans-=Dfs(S,INF);
    101          
    102         printf("%lld",Ans);
    103          
    104 }
    View Code
  • 相关阅读:
    Django ORM操作
    django路由系统
    django(模版)
    mysql(函数,存储过程,事务,索引)
    mysql(单表查询,多表查询,MySQl创建用户和授权,可视化工具Navicat的使用)
    pycharm基本用法
    JS在浏览器中输出各种三角形
    异常处理,内置方法(__new__,__init__,__del__析构方法,单例模式,item系列)
    反射,内置方法,__str__ __repr__
    C. Swap Letters 01字符串最少交换几次相等
  • 原文地址:https://www.cnblogs.com/BearChild/p/6426850.html
Copyright © 2011-2022 走看看