[网络流][带点权边权图的转换][BZOJ 2039]人员雇佣

Description

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

Analysis

嘛,这道题算是2007年国家队论文胡伯涛《最小割模型在信息学竞赛中的应用》的一个拓展运用吧。不过要注意的是一条边的权值被算了两次,还有算最小割时每条边的权值要乘个四...这里题目具体分析我不可能给得出。直接上代码吧...

var
  n,vs,vt,edge,num,i,j,x,u,ans:longint;
  e:array[1..1000000,1..3] of longint;
  d,vd,fr,p,du:array[0..1010] of longint;
procedure add(x,y,c:longint);
begin
  inc(edge); e[edge,1]:=y; e[edge,2]:=fr[x]; e[edge,3]:=c; fr[x]:=edge;
end;
function max(a,b:longint):longint;
begin
  if a>b then exit(a) else exit(b);
end;
function min(a,b:longint):longint;
begin
  if a<b then exit(a) else exit(b);
end;
function dfs(u,flow:longint):longint;
var
  k,tmp:longint;
begin
  if u=vt then exit(flow);
  dfs:=0;
  k:=fr[u];
  while k<>0 do begin
    if (e[k,3]>0) and (d[u]=d[e[k,1]]+1) then begin
      tmp:=dfs(e[k,1],min(e[k,3],flow-dfs));
      inc(dfs,tmp);
      dec(e[k,3],tmp);
      if odd(k) then inc(e[k+1,3],tmp) else inc(e[k-1,3],tmp);
      if dfs=flow then exit;
    end;
    k:=e[k,2];
  end;
  dec(vd[d[u]]);
  if vd[d[u]]=0 then d[vs]:=num;
  inc(d[u]);
  inc(vd[d[u]]);
end;
begin
  readln(n);
  vs:=0; vt:=n+1; num:=vt+1; vd[0]:=num;
  for i:=1 to n do read(p[i]);
  for i:=1 to n do begin
    for j:=1 to n do begin
      read(x);
      if j<=i then continue;
      inc(du[i],x+x); inc(du[j],x+x);
      add(i,j,x+x+x+x);
      add(j,i,x+x+x+x);
    end;
  end;
  for i:=1 to n do u:=max(u,du[i]-2*p[i]);
  for i:=1 to n do begin add(vs,i,u); add(i,vs,0); end;
  for i:=1 to n do begin add(i,vt,u+2*p[i]-du[i]); add(vt,i,0); end;
  while d[vs]<num do ans:=ans+dfs(vs,maxlongint);
  ans:=(u*n-ans) div 2;
  writeln(ans);
end.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值