zoukankan      html  css  js  c++  java
  • pku3662 Telephone Lines

    给一个n个点,m条边的图,每条边上有费用,求1到n的路径中最长边最小值,其中可以选择k条边不计费用

    最大最小问题,看见就二分答案

    布尔数组 d[i,j]表示在第i点,选择j条边免费,且其余边中最大值小于二分值,的状态是否可以达到

    用SPFA扩展即可,最后在d[i,0..k]中只要有一个是TRUE,该二分值就成立

    由我的程序,可以延伸出两种优化算法

    1.可以把d[i,j]表示到i点用了j条免费边后起点到当前点的最大值,一边SPFA之后,d[n,0..k]中的最小值就是答案。

    2.二分答案,d[i]记录超过答案的边数,如果最终d[n]<=k,则合法

    View Code
      1 program pku3662(input,output);
    2 type
    3 node = ^link;
    4 link = record
    5 goal : longint;
    6 w : int64;
    7 next : node;
    8 end;
    9 node2 = record
    10 now : longint;
    11 suml : int64;
    12 end;
    13 var
    14 l : array[0..1001] of node;
    15 d : array[0..1001,0..1001] of boolean;
    16 q : array[0..25001] of node2;
    17 v : array[0..1001,0..1001] of boolean;
    18 n,m,maxk : longint;
    19 procedure add(xx,yy: longint; ww:int64 );
    20 var
    21 t : node;
    22 begin
    23 new(t);
    24 t^.w:=ww;
    25 t^.goal:=yy;
    26 t^.next:=l[xx];
    27 l[xx]:=t;
    28 end; { add }
    29 procedure init;
    30 var
    31 i,xxx,yyy,www : longint;
    32 begin
    33 readln(n,m,maxk);
    34 for i:=1 to n do
    35 l[i]:=nil;
    36 for i:=1 to m do
    37 begin
    38 read(xxx,yyy,www);
    39 add(xxx,yyy,www);
    40 add(yyy,xxx,www);
    41 end;
    42 end; { init }
    43 function spfa(kill : int64 ):boolean;
    44 var
    45 head,tail,i : longint;
    46 t : node;
    47 begin
    48 fillchar(d,sizeof(d),false);
    49 fillchar(v,sizeof(v),false);
    50 head:=0;
    51 tail:=1;
    52 q[1].now:=1;
    53 q[1].suml:=0;
    54 d[1,0]:=true;
    55 v[1,0]:=true;
    56 while head<tail do
    57 begin
    58 inc(head);
    59 v[q[head].now,q[head].suml]:=false;
    60 t:=l[q[head].now];
    61 while t<>nil do
    62 begin
    63 if t^.w>kill then
    64 begin
    65 if q[head].suml<>maxk then
    66 if not d[t^.goal,q[head].suml+1] then
    67 begin
    68 d[t^.goal,q[head].suml+1]:=true;
    69 if not v[t^.goal,q[head].suml+1] then
    70 begin
    71 inc(tail);
    72 q[tail].now:=t^.goal;
    73 q[tail].suml:=q[head].suml+1;
    74 v[t^.goal,q[head].suml+1]:=true;
    75 end;
    76 end;
    77 end
    78 else
    79 begin
    80 if not d[t^.goal,q[head].suml] then
    81 begin
    82 d[t^.goal,q[head].suml]:=true;
    83 if not v[t^.goal,q[head].suml] then
    84 begin
    85 inc(tail);
    86 q[tail].now:=t^.goal;
    87 q[tail].suml:=q[head].suml;
    88 v[t^.goal,q[head].suml]:=true;
    89 end;
    90 end;
    91 end;
    92 t:=t^.next;
    93 end;
    94 end;
    95 for i:=0 to maxk do
    96 if d[n,i] then
    97 exit(true);
    98 exit(false);
    99 end; { spfa }
    100 procedure main;
    101 var
    102 left,right,mid : longint;
    103 begin
    104 if not spfa(maxlongint>>4) then
    105 begin
    106 writeln(-1);
    107 exit;
    108 end;
    109 if spfa(0) then
    110 begin
    111 writeln(0);
    112 exit;
    113 end;
    114 left:=0;
    115 right:=2000000;
    116 while left+1<right do
    117 begin
    118 mid:=(left+right)>>1;
    119 if spfa(mid) then
    120 right:=mid
    121 else
    122 left:=mid;
    123 end;
    124 writeln(right);
    125 end; { main }
    126 begin
    127 assign(input,'phoneline.in');reset(input);
    128 assign(output,'phoneline.out');rewrite(output);
    129 init;
    130 main;
    131 close(input);
    132 close(output);
    133 end.



  • 相关阅读:
    Android客户端与服务器交互方式-小结
    个人工作总结01
    第7周学习进度
    第6周学习进度
    PHP_D4_“简易聊天室 ”的具体技术实现
    php_D3_“简易聊天室 ”实现的关键技术 详解
    团队介绍
    最大联通子数组
    构建之法阅读笔记04
    大道至简阅读笔记04
  • 原文地址:https://www.cnblogs.com/neverforget/p/2371671.html
Copyright © 2011-2022 走看看