zoukankan      html  css  js  c++  java
  • bzoj2039

    还是同一类最小割问题

    对于只要记住,建图是来最小化损失,

    最大化收益是所有收益-最小取不到的收益

    首先对于每个经理i,如果不取,必然有signma(w[i,j])收益会得不到(这里我们先不考虑额外的损失);

    如果取,必然会损失a[i](其实这个也不是收益,只是我们最后用sum-mincut时,sum不包括a[i],就相当于损失了);

    下面考虑额外损失,对于i,j不在同一集合内(假设i被雇佣而j不被雇佣),会再损失2*w[i,j];

    为什么是2倍呢,从建图来看,如果这样做最小割,雇佣i,不雇佣j,那么w[i,j]这个收益会被取到一次,而事实上不仅取不到还要额外损失,然后我们还要再减去一个经理之间的额外影响(由题意),所以是2倍;

    然后分析完之后带入例子验证一下即可;

    建图就不多说了

      1 const inf=2147483647;
      2 type node=record
      3        next,flow,point:longint;
      4      end;
      5 
      6 var edge:array[0..4400010] of node;
      7     d,p,cur,pre,h,numh:array[0..1010] of longint;
      8     t,len,n,m,i,j,x,s,ans:longint;
      9 
     10 function min(a,b:longint):longint;
     11   begin
     12     if a>b then exit(b) else exit(a);
     13   end;
     14 
     15 procedure add(x,y,f:longint);
     16   begin
     17     inc(len);
     18     edge[len].point:=y;
     19     edge[len].flow:=f;
     20     edge[len].next:=p[x];
     21     p[x]:=len;
     22   end;
     23 
     24 function sap:longint;
     25   var neck,i,j,tmp,u,q:longint;
     26   begin
     27     numh[0]:=t+1;
     28     sap:=0;
     29     neck:=inf;
     30     for i:=0 to t do
     31       cur[i]:=p[i];
     32     u:=0;
     33     while h[0]<t+1 do
     34     begin
     35       d[u]:=neck;
     36       i:=cur[u];
     37       while i<>-1 do
     38       begin
     39         j:=edge[i].point;
     40         if (edge[i].flow>0) and (h[u]=h[j]+1) then
     41         begin
     42           cur[u]:=i;
     43           pre[j]:=u;
     44           neck:=min(neck,edge[i].flow);
     45           u:=j;
     46           if u=t then
     47           begin
     48             while u<>0 do
     49             begin
     50               u:=pre[u];
     51               j:=cur[u];
     52               dec(edge[j].flow,neck);
     53               inc(edge[j xor 1].flow,neck);
     54             end;
     55             sap:=sap+neck;
     56             neck:=inf;
     57           end;
     58           break;
     59         end;
     60         i:=edge[i].next;
     61       end;
     62       if i=-1 then
     63       begin
     64         dec(numh[h[u]]);
     65         if numh[h[u]]=0 then exit;
     66         i:=p[u];
     67         tmp:=t;
     68         q:=-1;
     69         while i<>-1 do
     70         begin
     71           j:=edge[i].point;
     72           if (edge[i].flow>0) and (h[j]<tmp) then
     73           begin
     74             tmp:=h[j];
     75             q:=i;
     76           end;
     77           i:=edge[i].next;
     78         end;
     79         cur[u]:=q;
     80         h[u]:=tmp+1;
     81         inc(numh[h[u]]);
     82         if u<>0 then
     83         begin
     84           u:=pre[u];
     85           neck:=d[u];
     86         end;
     87       end;
     88     end;
     89   end;
     90 
     91 begin
     92   len:=-1;
     93   readln(n);
     94   fillchar(p,sizeof(p),255);
     95   t:=n+1;
     96   for i:=1 to n do
     97   begin
     98     read(x);
     99     add(i,t,x);
    100     add(t,i,0);
    101   end;
    102   for i:=1 to n do
    103   begin
    104     s:=0;
    105     for j:=1 to n do
    106     begin
    107       read(x);
    108       s:=s+x;
    109       if i<>j then
    110       begin
    111         add(i,j,x shl 1);
    112         add(j,i,0);
    113       end;
    114     end;
    115     add(0,i,s);
    116     add(i,0,0);
    117     ans:=ans+s;
    118   end;
    119   writeln(ans-sap);
    120 end.
    View Code
  • 相关阅读:
    【转】WPF DataGridComboBoxColumn使用
    【转】CAD 二次开发--属性块 Block和BlockReference
    【转】【Revit】Revit二次开发——读取cad中的文字信息
    【转】【Centos】Linux(Centos7)下搭建SVN服务器
    现代php编程
    drone实践记录
    PHP拆分YAPI导出的swagjson文件
    pydantic验证器Validator
    利用notion打造读书追逐系统
    opencv马赛克python实现
  • 原文地址:https://www.cnblogs.com/phile/p/4473215.html
Copyright © 2011-2022 走看看