zoukankan      html  css  js  c++  java
  • bzoj2039

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

    思路:

          把点集分成两个,很容易想到最小割模型。。

          但是最小割求出来的是最少去掉的。。

          所以我们想到了补集。。先所有都取然后去掉最少的。。

          建图如下:

              <S, i, sigma(E[i,j]) >

               <i, T, a[i]>

               <i, j, 2 * E[i][j]>

        最后跑一遍最大流。。

        答案即为sum(E[i][j]) - maxflow

    code:

      1 /*
      2  * Author:  Yzcstc
      3  * Created Time:  2014/10/25 19:54:45
      4  * File Name: bzoj2039.cpp
      5  */
      6 #include<cstdio>
      7 #include<iostream>
      8 #include<cstring>
      9 #include<cstdlib>
     10 #include<cmath>
     11 #include<algorithm>
     12 #include<string>
     13 #include<map>
     14 #include<set>
     15 #include<vector>
     16 #define M0(a) memset(a, 0, sizeof(a))
     17 using namespace std;
     18 typedef long long ll;
     19 const int maxn = 1100;
     20 const int Inf = 0x3fffffff;
     21 const int maxm = 3100000;
     22 struct oo{
     23       int y, next;
     24       ll f;
     25 };
     26 struct MaxFlow{
     27        int n, S, T, tot;
     28        int son[maxn], dist[maxn], gap[maxn];
     29        oo e[maxm];
     30        ll sap(int x,ll aug){
     31            if (x == T) return aug;
     32            int mind = n;
     33            ll sum = 0, f;
     34            for (int p = son[x]; p != -1; p = e[p].next){
     35                   int y = e[p].y;
     36                   if (dist[y] + 1 == dist[x] && e[p].f){
     37                        f = sap(y, min(e[p].f, aug - sum));
     38                        e[p].f -= f;
     39                        e[p^1].f += f;
     40                        sum += f;
     41                        if (sum == aug || dist[S] >= n) return sum;
     42                   }
     43                   if (e[p].f) mind = min(mind, dist[y]);
     44            }
     45            if (!sum){
     46                if (!(--gap[dist[x]])) dist[S] = n;
     47                ++gap[dist[x] = mind + 1];
     48            }
     49            return sum;
     50        }
     51 
     52        void add(int x, int y, ll f){
     53             e[tot].y = y; e[tot].f = f;
     54             e[tot].next = son[x]; son[x] = tot++;
     55             e[tot].y = x; e[tot].f = 0;
     56             e[tot].next = son[y]; son[y] = tot++;
     57        }
     58 
     59        void init(int S, int T, int n){
     60             memset(son, -1, sizeof(son));
     61             tot = 0;
     62             this->S = S, this->T = T, this->n = n;
     63        }
     64        ll maxflow(){
     65             M0(gap);
     66             M0(dist);
     67             gap[0] = n;
     68             ll ans = 0;
     69             while (dist[S] < n) ans += sap(S, Inf);
     70             return ans;
     71        }
     72 } F;
     73 int a[1200], n, m;
     74 ll s[1200];
     75 int e[1200][1200];
     76 void solve(){
     77      for (int i = 1; i <= n; ++i)
     78            scanf("%d", &a[i]);
     79      M0(s);
     80      ll sum = 0;
     81      for (int i = 1; i <= n; ++i){
     82           for (int j = 1; j <= n; ++j)
     83                scanf("%d", &e[i][j]), s[i] += e[i][j], sum += e[i][j];
     84      }
     85      int S = 0,  T = n + 1;
     86      F.init(S, T, T + 1);
     87      for (int i = 1; i <= n; ++i)
     88           F.add(S, i, a[i]), F.add(i, T, s[i]);
     89      for (int i = 1; i <= n; ++i)
     90          for (int j = 1; j <= n; ++j) if (i != j)
     91                if (e[i][j] > 0) F.add(i, j, e[i][j] << 1);
     92      sum -= F.maxflow();
     93      cout << sum << endl;
     94 }
     95 
     96 int main(){
     97     while (scanf("%d", &n) != EOF){
     98           solve();
     99     }
    100     return 0;
    101 }
    View Code
  • 相关阅读:
    c# 根据当前时间获取,本周,本月,本季度,月初,月末,各个时间段
    Button 对 TreeView1 所有节点的全选
    启动Myeclipse报错“Failed to create the Java Virtual Machine”的解决办法
    Myeclipse 启动报错 Failed to create the java Virtual Machine
    ng-cordova和cordova区别
    Java高效计数器
    WebView 简介
    Hibernate——(4)Hibernate映射类型
    Hibernate——(3)主键生成方式
    Hibernate——(2)增删改查
  • 原文地址:https://www.cnblogs.com/yzcstc/p/4050855.html
Copyright © 2011-2022 走看看