• bzoj3130


    这道题要谈很多;

    首先,第一问等会我另外说一下;

    第二问比较难想,首先我们的考虑两人的最优策略是什么

    对于Bob,我们令分配了x条边的费用,则我们要最大化

    ans=Σ(i=1 to x) flow[i] * p/x  (flow[i]为选择的边)

    显然ans<=x*maxflow[i]*p/x=maxflow[i]*p 

    显然ans最大的方案就是将费用全部分配到实际流量最大的那条边上去

    这样Alice的方案也明确了,就是在维持最大流不变的前提下,是实际流量最大的那条边最小

    对于这类最小化最大的问题,我们不难想到二分答案,二分网络流上界流量

    但请注意,有没有从题目保留的精度想到什么呢?

    对,这道题流量可以是实数,

    对于任意实数的网络流是不可做的,但是在一定精度范围内就照样可行;

    照样就没什么问题了

    这里说下我发现我以前写的最大流sap是不够好的

    没加当前弧优化,之前很多题没TLE真是万幸;

    在bzoj2127(之后放在一个专题写)中体现的特别明显,如果只用sap+gap妥妥TLE

    用了之后1s多跑完……

    这里给出最终的最大流写法(sap+gap+cur)

      1 const inf=500000007;
      2       ok=1e-6;  //控制精读
      3 type node=record
      4        next,point:longint;
      5        flow:double;
      6      end;
      7 
      8 var edge:array[0..20100] of node;
      9     cur,numh,p,h,pre:array[0..150] of longint;
     10     w,x,y:array[0..2010] of longint;
     11     d:array[0..150] of double;
     12     l,r,mid,ans1,ans2:double;
     13     t,len,i,n,m:longint;
     14 
     15 function min(a,b:double):double;
     16   begin
     17     if a>b then exit(b) else exit(a);
     18   end;
     19 
     20 procedure add(x,y:longint;f:double);
     21   begin
     22     inc(len);
     23     edge[len].flow:=f;
     24     edge[len].point:=y;
     25     edge[len].next:=p[x];
     26     p[x]:=len;
     27   end;
     28 
     29 function sap(k:double):double;  //带当前弧优化
     30   var u,i,j,tmp,q:longint;
     31       neck:double;
     32       flag:boolean;
     33   begin
     34     len:=-1;
     35     fillchar(p,sizeof(p),255);
     36     for i:=1 to m do
     37     begin
     38       add(x[i],y[i],min(k,w[i]));
     39       add(y[i],x[i],0);
     40     end;
     41     fillchar(numh,sizeof(numh),0);
     42     fillchar(h,sizeof(h),0);
     43     numh[0]:=n;
     44     u:=1;
     45     neck:=inf;
     46     sap:=0;
     47     cur:=p;
     48     while h[1]<n do
     49     begin
     50       d[u]:=neck;
     51       flag:=false;
     52       i:=cur[u];
     53       while i<>-1 do
     54       begin
     55         j:=edge[i].point;
     56         if (edge[i].flow>0) and (h[u]=h[j]+1) then
     57         begin
     58           flag:=true;
     59           cur[u]:=i;
     60           pre[j]:=u;
     61           neck:=min(neck,edge[i].flow);
     62           u:=j;
     63           if u=n then
     64           begin
     65             sap:=sap+neck;
     66             while u<>1 do
     67             begin
     68               u:=pre[u];
     69               j:=cur[u];
     70               edge[j].flow:=edge[j].flow-neck;
     71               edge[j xor 1].flow:=edge[j xor 1].flow+neck;
     72             end;
     73             neck:=inf;  //勿忘1
     74           end;
     75           break;
     76         end;
     77         i:=edge[i].next;
     78       end;
     79       if not flag then
     80       begin
     81         dec(numh[h[u]]);
     82         if numh[h[u]]=0 then exit;
     83         tmp:=n;
     84         i:=p[u];
     85         q:=0;
     86         while i<>-1 do
     87         begin
     88           j:=edge[i].point;
     89           if (tmp>h[j]) and (edge[i].flow>0) then
     90           begin
     91             q:=i;
     92             tmp:=h[j];
     93           end;
     94           i:=edge[i].next;
     95         end;
     96         h[u]:=tmp+1;
     97         cur[u]:=q;     //勿忘2
     98         inc(numh[h[u]]);
     99         if u<>1 then
    100         begin
    101           u:=pre[u];
    102           neck:=d[u];   //记录当前瓶颈边的作用
    103         end;
    104       end;
    105     end;
    106   end;
    107 
    108 begin
    109   readln(n,m,t);
    110   for i:=1 to m do
    111   begin
    112     readln(x[i],y[i],w[i]);
    113     if r<w[i] then r:=w[i];
    114   end;
    115   l:=0;
    116   ans1:=sap(r);
    117   while r-l>ok do   //实数范围内的二分答案
    118   begin
    119     mid:=(l+r)/2;
    120     if abs(ans1-sap(mid))<ok then r:=mid
    121     else l:=mid;
    122   end;
    123   writeln(ans1:0:0);
    124   writeln(r*t:0:4);
    125 end.
    View Code
  • 相关阅读:
    vsftpd 配置:chroot_local_user与chroot_list_enable详解
    rsync同步目录
    apache
    centos 7 服务管理
    PowerPoint’s Menu is Too Big
    测试网页返回值
    作为人的展现方式
    Java 日期与时间
    Java 随机数
    Character 类
  • 原文地址:https://www.cnblogs.com/phile/p/4473229.html
Copyright © 2020-2023  润新知