zoukankan      html  css  js  c++  java
  • poj2391,poj2455

    这两题本质是一致的;

    一般来说,对于最长(短)化最短(长)的问题我们一般都使用二分答案+判定是否可行

    因为这样的问题,我们一旦知道答案,就能知道全局信息

    拿poj2455举例,对于二分出的一个答案,我们将不符合的边全部去掉,在做一遍最大流判断是否成立即可

    注意这道题有重边,所以用链式前向星比较好(TT,当时我用的数组模拟邻接表表不要太烦)

      1 type node=record
      2        po,flow,cost:longint;
      3      end;
      4 var w,ow:array[0..205,0..5000] of node;
      5     cur,pre,numh,h,s,s0:array[0..500] of longint;
      6     ans,max,mid,l,r,x,y,z,i,n,m,p:longint;
      7 
      8 procedure add(x,y,z,f:longint);  //很繁琐的结构,需要检查好久,重边优先选择链式前向星,比较方便
      9   begin
     10     inc(s[x]);
     11     w[x,s[x]].po:=y;
     12     w[x,s[x]].cost:=z;
     13     w[x,s[x]].flow:=f;
     14   end;
     15 
     16 function maxflow(k:longint):boolean;  //很喜欢写sap,判定
     17   var j,sum,u,i,t,r,tmp:longint;
     18   begin
     19     max:=-1;
     20     fillchar(pre,sizeof(pre),255);
     21     fillchar(cur,sizeof(cur),255);
     22     fillchar(h,sizeof(h),0);
     23     fillchar(numh,sizeof(numh),0);   //一定要注意,这句话没有不影响程序结果,但会拖慢程序速度(相当于没用到GAP优化),谨记
     24     fillchar(s0,sizeof(s0),0);
     25     for i:=1 to n do
     26       for j:=1 to s[i] do
     27       begin
     28         if w[i,j].cost<=k then     //根据条件构造新图
     29         begin
     30           inc(s0[i]);
     31           ow[i,s0[i]]:=w[i,j];
     32         end;
     33       end;
     34     numh[0]:=n;
     35     sum:=0;
     36     u:=1;
     37     while h[1]<n do
     38     begin
     39       if u=n then
     40       begin
     41         i:=1;
     42         while i<>n do
     43         begin
     44           t:=cur[i];
     45           if max<ow[i,t].cost then max:=ow[i,t].cost;  //小优化而已,在最大流里面找一条最大的边,实际上答案是这个
     46           dec(ow[i,t].flow);
     47           i:=ow[i,t].po;
     48         end;
     49         inc(sum);
     50         if sum=p then exit(true);
     51         u:=1;
     52       end;
     53       r:=-1;
     54       for i:=1 to s0[u] do
     55         if (ow[u,i].flow>0) and (h[u]=h[ow[u,i].po]+1) then
     56         begin
     57           r:=i;
     58           break;
     59         end;
     60 
     61       if r<>-1 then
     62       begin
     63         cur[u]:=r;
     64         pre[ow[u,r].po]:=u;
     65         u:=ow[u,r].po;
     66       end
     67       else begin
     68         dec(numh[h[u]]);
     69         if numh[h[u]]=0 then exit(false);   
     70         tmp:=n;   //注意这里千万不要顺手打成maxlongint之类
     71         for i:=1 to s0[u] do
     72           if (ow[u,i].flow>0) and (tmp>h[ow[u,i].po]) then tmp:=h[ow[u,i].po];
     73         h[u]:=tmp+1;
     74         inc(numh[h[u]]);
     75         if u<>1 then u:=pre[u];
     76       end;
     77     end;
     78     exit(false);
     79   end;
     80 
     81 begin
     82   readln(n,m,p);
     83   for i:=1 to m do
     84   begin
     85     readln(x,y,z);
     86     add(x,y,z,1);
     87     add(y,x,z,1);
     88     if z>r then r:=z;
     89   end;
     90   l:=1;
     91   while l<=r do
     92   begin
     93     mid:=(l+r) shr 1;
     94     if maxflow(mid) then  
     95     begin
     96       ans:=max;   //小小的优化,但不是所有二分判定都可以用
     97       r:=max-1;
     98     end
     99     else l:=mid+1;
    100   end;
    101   writeln(ans);
    102 end.
    View Code

    poj2391也是一样的,只不过多了floyd预处理

    一般的,对于答案越大,决策就越有可能成功的这类具有单调性的题目,通常使用二分答案

  • 相关阅读:
    聊一聊Java泛型的擦除
    微信退款通知信息解密
    Spring Boot 初识
    shiro初识
    Redis 初探
    Java Json库的选取准则
    JAVA 几款Json library的比较
    FUSE简介
    Lab 2 源码分析
    Lab2
  • 原文地址:https://www.cnblogs.com/phile/p/4473276.html
Copyright © 2011-2022 走看看