[Bzoj2039][2009国家集训队]employ人员雇佣(最小割)

2039: [2009国家集训队]employ人员雇佣



Time Limit: 20 Sec  Memory Limit: 259 MB
Submit: 1988  Solved: 951
[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

【数据规模和约定】
20%的数据中N<=10
50%的数据中N<=100
100%的数据中 N<=1000, Ei,j<=maxlongint, Ai<=maxlongint

HINT


Source


版权所有者: 林衍凯

分析:


最小割。

s连i 权值为ai

i连t 权值为∑e[i][j]

i连j  权值为2 * e[i][j]

想了半天,我还是滚回去好好啃啃各种论文把。。

AC代码:


# include <iostream>
# include <cstdio>
# include <queue>
# include <cstring>
using namespace std;
typedef long long LL;
const LL inf = 1e16;
const int N = 2e3 + 12;
int head[N],dt,s,t,cur[N],dep[N],n;LL bac;
struct Edge{
    int to,nex;LL res;
}edge[N * N];
void AddEdge(int u,int v,LL w)
{
    edge[dt] = (Edge){v,head[u],w};
    head[u] = dt++;
    edge[dt] = (Edge){u,head[v],0};
    head[v] = dt++;
}
queue<int> Q;
bool Bfs()
{
    for(int i = s;i <= t;i++)dep[i] = -1;
    dep[s] = 1;Q.push(s);int u;
    while(!Q.empty())
    {
     u = Q.front();Q.pop();
     for(int i = head[u];~i;i = edge[i].nex)if(dep[edge[i].to] == -1 && edge[i].res)
     {
        dep[edge[i].to] = dep[u] + 1;
        Q.push(edge[i].to);
     }
    }
    return dep[t] != -1;
}
LL dfs(int u,LL f)
{
    if(u == t || !f)return f;
    LL flow = 0,D;
    for(int &i = cur[u];~i;i = edge[i].nex)if(dep[edge[i].to] == dep[u] + 1 && (D = dfs(edge[i].to,min(f,edge[i].res))))
    {
        edge[i].res -= D;edge[i ^ 1].res += D;
        f -= D;flow += D;
        if(!f)break;
    }
    return flow;
}
LL Dinic()
{
    LL flow = 0;
    while(Bfs())
    {
        for(int i = s;i <= t;i++)cur[i] = head[i];
        flow += dfs(s,inf);
    }
    return flow;
}
int main()
{
  memset(head,-1,sizeof head);
  scanf("%d",&n);s = 0;t = n + 1;
  LL x,ret;
  for(int i = 1;i <= n;i++)scanf("%lld",&x),AddEdge(s,i,x);
  for(int i = 1;i <= n;i++)
  {
   ret = 0;
   for(int j = 1;j <= n;j++)
   {
       scanf("%lld",&x);
       AddEdge(i,j,x << 1LL);bac += x;
       ret += x;
   }
   AddEdge(i,t,ret);
  }
  printf("%lld\n",bac - Dinic());
}

原文地址:https://www.cnblogs.com/lzdhydzzh/p/8782587.html

时间: 2024-10-12 18:53:55

[Bzoj2039][2009国家集训队]employ人员雇佣(最小割)的相关文章

BZOJ 2039 2009国家集训队 employ人员雇佣 最小割

题目大意:给定n个人,每个人有一个佣金,i和j如果同时被雇佣会产生2*E(i,j)的效益,i和j如果一个被雇佣一个不被雇佣会产生E(i,j)的亏损,求最大收益 首先对于每一个cost[i],从点i出发向汇点连一条流量为cost[i]的边 对于每一对点(i,j),建图如下: 从S向点i和点j各连一条流量为E(i,j)的边 i和j之间连一条流量为2*E(i,j)的双向边 这样可以保证每种割法对应一种雇佣方案 用矩阵上数字的总和减掉最小割即是答案 边集会很大,因此合并后再加即可 #include <c

【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,对于一些经理可能他做出的贡献不值得

BZOJ2039 [2009国家集训队]employ人员雇佣

一开始就知道是最小割模型,然后开始乱搞建图,发现自己想错了... Orz PoPoQQQ,还给蒟蒻提供了很多帮助! 1 /************************************************************** 2 Problem: 2039 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:5984 ms 7 Memory:64264 kb 8 *************************

【BZOJ 2039】 2039: [2009国家集训队]employ人员雇佣 (最小割)

2039: [2009国家集训队]employ人员雇佣 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1511  Solved: 728 Description 作为一个富有经营头脑的富翁,小L决定从本国最优秀的经理中雇佣一些来经营自己的公司.这些经理相互之间合作有一个贡献指数,(我们用Ei,j表示i经理对j经理的了解程度),即当经理i和经理j同时被雇佣时,经理i会对经理j做出贡献,使得所赚得的利润增加Ei,j.当然,雇佣每一个经理都需要花费一定

BZOJ 2039: [2009国家集训队]employ人员雇佣

2039: [2009国家集训队]employ人员雇佣 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1369  Solved: 667[Submit][Status][Discuss] Description 作为一个富有经营头脑的富翁,小L决定从本国最优秀的经理中雇佣一些来经营自己的公司.这些经理相互之间合作有一个贡献指数,(我们用Ei,j表示i经理对j经理的了解程度),即当经理i和经理j同时被雇佣时,经理i会对经理j做出贡献,使得所赚得的利

BZOJ_2039_[2009国家集训队]employ人员雇佣_ 最小割

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

2009国家集训队 employ人员雇佣

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

2039: [2009国家集训队]employ人员雇佣

任意门 Description 作为一个富有经营头脑的富翁,小L决定从本国最优秀的经理中雇佣一些来经营自己的公司.这些经理相互之间合作有一个贡献指数,(我们用Ei,j表示i经理对j经理的了解程度),即当经理i和经理j同时被雇佣时,经理i会对经理j做出贡献,使得所赚得的利润增加Ei,j.当然,雇佣每一个经理都需要花费一定的金钱Ai,对于一些经理可能他做出的贡献不值得他的花费,那么作为一个聪明的人,小L当然不会雇佣他. 然而,那些没有被雇佣的人会被竞争对手所雇佣,这个时候那些人会对你雇佣的经理的工作

BZOJ 2039 [2009国家集训队]employ人员雇佣 网络流

链接 BZOJ 2039 题解 这题建图好神,自己瞎搞了半天,最后不得不求教了企鹅学长的博客,,,,发现建图太神了!! s向每个人连sum(e[i][x]) 的边,每个人向T连a[i]的边.两两人之间连2 * e[i][j]的边即可. 最后总的e – maxflow即为答案. 为什么我就没想到"源点向每个人连sum(e[i][x]) 的边"-- 犯的错误: 为了方便,对于双向边,用ADD(u, v, w), ADD(v, u, w)代替了ADD(u, v, w), ADD(v, u,