zoukankan      html  css  js  c++  java
  • bzoj1532

    就题目而言,这道题是裸的二分+最大流

    但是这样是TLE的,我们考虑优化

    1. 我们可以先贪心,这样二分的上界就可以缩小了

    2. 最大流我们可以不急着跑增广路,我们可以先贪心一个流然后再跑增广路

    但是我们发现上述优化还是不足以通过这题

    我们考虑是不是sap不适合处理这张图(这是二分图)呢?确实是这样的

    考虑到sap判断h[s]<t+1,但实际上二分图的增广路不可能太长,我们把这个条件改成h[s]<100

    duang的一下,就飞快的跑过了(460ms)

    而事实证明dinic似乎没有这种问题,因为根据证明,dinic跑二分图和HK算法是一样的复杂度

      1 type node=record
      2        po,next,flow:longint;
      3      end;
      4 
      5 var e:array[0..200010] of node;
      6     w,pre,numh,p,h,cur,x,y:array[0..20010] of longint;
      7     ans,t,i,n,m,l,r,mid,len,need:longint;
      8 
      9 procedure add(x,y,f:longint);
     10   begin
     11     inc(len);
     12     e[len].po:=y;
     13     e[len].flow:=f;
     14     e[len].next:=p[x];
     15     p[x]:=len;
     16   end;
     17 
     18 procedure build(x,y,f1,f2:longint);
     19   begin
     20     add(x,y,f1);
     21     add(y,x,f2);
     22   end;
     23 
     24 function sap:longint;
     25   var i,j,q,u,tmp:longint;
     26   begin
     27     fillchar(numh,sizeof(numh),0);
     28     fillchar(h,sizeof(h),0);
     29     for i:=0 to t do
     30       cur[i]:=p[i];
     31     u:=0; sap:=0;
     32     while (h[0]<t+1) and (h[0]<100) do  //重要优化
     33     begin
     34       i:=cur[u];
     35       while i<>-1 do
     36       begin
     37         j:=e[i].po;
     38         if (e[i].flow>0) and (h[u]=h[j]+1) then
     39         begin
     40           cur[u]:=i;
     41           pre[j]:=u;
     42           u:=j;
     43           if u=t then
     44           begin
     45             inc(sap);
     46             if sap=need then exit;
     47             while u<>0 do
     48             begin
     49               u:=pre[u];
     50               j:=cur[u];
     51               dec(e[j].flow);
     52               inc(e[j xor 1].flow);
     53             end;
     54           end;
     55           break;
     56         end;
     57         i:=e[i].next;
     58       end;
     59       if i=-1 then
     60       begin
     61         dec(numh[h[u]]);
     62         if numh[h[u]]=0 then exit;
     63         i:=p[u];
     64         tmp:=t;
     65         q:=-1;
     66         while i<>-1 do
     67         begin
     68           j:=e[i].po;
     69           if e[i].flow>0 then
     70             if tmp>h[j] then
     71             begin
     72               q:=i;
     73               tmp:=h[j];
     74             end;
     75           i:=e[i].next;
     76         end;
     77         h[u]:=tmp+1;
     78         inc(numh[h[u]]);
     79         cur[u]:=q;
     80         if u<>0 then u:=pre[u];
     81       end;
     82     end;
     83   end;
     84 
     85 procedure swap(var a,b:longint);
     86   var c:longint;
     87   begin
     88     c:=a;
     89     a:=b;
     90     b:=c;
     91   end;
     92 
     93 function check(h:longint):boolean;
     94   var i:longint;
     95   begin
     96     len:=-1;
     97     fillchar(p,sizeof(p),255);
     98     need:=0;
     99     for i:=1 to n do
    100       w[i]:=h;
    101     for i:=1 to m do  //贪心初始流
    102     begin
    103       if w[x[i]]<w[y[i]] then swap(x[i],y[i]);
    104       if w[x[i]]=0 then
    105       begin
    106         build(i,x[i]+m,1,0);
    107         build(0,i,1,0);
    108         inc(need);
    109       end
    110       else begin
    111         dec(w[x[i]]);
    112         build(0,i,0,1);
    113         build(i,x[i]+m,0,1);
    114       end;
    115       build(i,y[i]+m,1,0);
    116     end;
    117     if need=0 then exit(true);
    118     for i:=1 to n do
    119       build(i+m,t,w[i],h-w[i]);
    120     if sap=need then exit(true) else exit(false);
    121   end;
    122 
    123 begin
    124   readln(n,m);
    125   for i:=1 to m do
    126   begin
    127     readln(x[i],y[i]);
    128     if w[x[i]]<w[y[i]] then inc(w[x[i]]) else inc(w[y[i]]);
    129   end;
    130   for i:=1 to n do
    131     if w[i]>r then r:=w[i];  //贪心上界
    132   t:=n+m+1;
    133   l:=0;
    134   while l<=r do
    135   begin
    136     mid:=(l+r) shr 1;
    137     if check(mid) then
    138     begin
    139       ans:=mid;
    140       r:=mid-1;
    141     end
    142     else l:=mid+1;
    143   end;
    144   writeln(ans);
    145 end.
    View Code
  • 相关阅读:
    实例属性 类属性 实例域 类域
    研究数据集
    static 静态域 类域 静态方法 工厂方法 he use of the static keyword to create fields and methods that belong to the class, rather than to an instance of the class 非访问修饰符
    accessor mothod mutator mothod 更改器方法 访问器方法 类的方法可以访问类的任何一个对象的私有域!
    上钻 下钻 切片 转轴 降采样
    识别会话
    Performance Tuning Using Linux Process Management Commands
    Secure Hash Algorithm 3
    grouped differently across partitions
    spark 划分stage Wide vs Narrow Dependencies 窄依赖 宽依赖 解析 作业 job stage 阶段 RDD有向无环图拆分 任务 Task 网络传输和计算开销 任务集 taskset
  • 原文地址:https://www.cnblogs.com/phile/p/4490710.html
Copyright © 2011-2022 走看看