zoukankan      html  css  js  c++  java
  • 5771. 【NOIP2008模拟】遨游

    Description

         MWH寒假外出旅游,来到了S国。S国划分为N个省,第i个省有Ti座城市,编号分别为Ci1,Ci2,……CiTi(各省城市编号不会重复)。所有城市间有M条双向的道路连接,从任意一个城市出发,可到达一切城市,每条道路均须收费。
         此时恰逢春运期间,S国交通运输局采取了优惠措施。当一条路的路费在[L..R]区间时,可免去。同时,每个省也有优惠措施,第i个省内的每条道路路费收其Xi%,连接第i个省和第j个省的每条道路路费收其(Xi%+Xj%)/2。
    MWH想从城市s走到城市t,请求出一对L,R,确保:
    1. MWH能免费到达目的地;
    2. L≤R;
    3. L、R均为整数;
    4. L尽可能地大,R在满足L最大的前提下最小。

    注意:因每条道路由各省的交通运输局直接管辖,所以每条道路的路费必须先得到省级优惠,再得到国家级优惠。
     

    Input

    第一行两个整数N,M。
    接下来M行,每行三个整数,u、v、w,表示连接u、v的道路需收费w。
    接下来N行,第i+M+1行有一个整数Ti,后面Ti个整数,分别是Ci1..CiTi(所有城市编号保证按正整数顺序给出1..  Ti)。
    下一行N个整数X1..Xi。
    最后一行,两个整数,s、t。
     

    Output

    一行两个整数,如题,L和R。
     
    Solutions

    对于题目描述中既有“最大”又有“最小”的题目,很多都是用二分,这题也不例外。

    首先,省级路费是很容易算且是独立的,所以预处理出每条道路经过了省级优惠后是多少路费。

    接着,这题要用到二分嵌套。第一层是二分L(l,r,mid),第二层是二分R(l1,r1,mid1),中间要做一次搜索。把所有在[L..R]区间内的边取出,做一遍搜索,如果能到达目的地则记录mid1,并将r1改小,否则将l1改大。第一重二分中如果能取到mid1则记录下mid与mid1,并将l1改大,否则将r1改小。

    代码

      1 type
      2   arr=record
      3     y,next:longint;
      4     w:real;
      5   end;
      6 var
      7   n,m,nm,qq,zz,maxl,maxr:longint;
      8   a:array [0..400001] of arr;
      9   ls,list,v,bo:array [0..400001] of longint;
     10   b,bz:array [0..50001] of longint;
     11 
     12 procedure add(x,y:longint;z:real);
     13 begin
     14   inc(nm);
     15   a[nm].y:=y; a[nm].w:=z;
     16   a[nm].next:=ls[x]; ls[x]:=nm;
     17 end;
     18 
     19 procedure init;
     20 var
     21   i,j,t,k:longint;
     22   x,y:array [0..200001] of longint;
     23   z:array [0..200001] of real;
     24 begin
     25   readln(n,m);
     26   nm:=0;
     27   for i:=1 to m do
     28     readln(x[i],y[i],z[i]);
     29   for i:=1 to n do
     30     begin
     31       read(t);
     32       for j:=1 to t do
     33         begin
     34           read(k);
     35           b[k]:=i;
     36         end;
     37     end;
     38   for i:=1 to n do
     39     read(bz[i]);
     40   readln(qq,zz);
     41   for i:=1 to m do
     42     begin
     43       if b[x[i]]=b[y[i]] then z[i]:=z[i]*bz[b[x[i]]]/100
     44                          else z[i]:=z[i]*(bz[b[x[i]]]+bz[b[y[i]]])/200;
     45       add(x[i],y[i],z[i]);
     46       add(y[i],x[i],z[i]);
     47     end;
     48 end;
     49 
     50 function max(o,p:real):real;
     51 begin
     52   if o>p then exit(o);
     53   exit(p);
     54 end;
     55 
     56 function min(o,p:real):real;
     57 begin
     58   if o<p then exit(o);
     59   exit(p);
     60 end;
     61 
     62 function bfs1(ll:longint):boolean;
     63 var
     64   i,j,k,h,t:longint;
     65 begin
     66   fillchar(bo,sizeof(bo),0);
     67   fillchar(v,sizeof(v),0);
     68   fillchar(list,sizeof(list),0);
     69   h:=0; t:=1;
     70   v[qq]:=1; list[1]:=qq; bo[qq]:=1;
     71   repeat
     72     h:=h+1;
     73     j:=ls[list[h]];
     74     while j<>0 do
     75       begin
     76         with a[j] do
     77           begin
     78             if w-ll>=0 then
     79               begin
     80                 if bo[y]=0 then
     81                   begin
     82                     bo[y]:=1;
     83                     if v[y]=0 then
     84                       begin
     85                         t:=t+1;
     86                         list[t]:=y;
     87                         v[y]:=1;
     88                       end;
     89                   end;
     90               end;
     91             j:=next;
     92           end;
     93       end;
     94     v[list[h]]:=0;
     95   until h=t;
     96   if bo[zz]=1 then exit(true)
     97               else exit(false);
     98 end;
     99 
    100 function bfs2(ll:longint):boolean;
    101 var
    102   i,j,k,h,t:longint;
    103 begin
    104   fillchar(bo,sizeof(bo),0);
    105   fillchar(v,sizeof(v),0);
    106   fillchar(list,sizeof(list),0);
    107   h:=0; t:=1;
    108   v[qq]:=1; list[1]:=qq; bo[qq]:=1;
    109   repeat
    110     h:=h+1;
    111     j:=ls[list[h]];
    112     while j<>0 do
    113       begin
    114         with a[j] do
    115           begin
    116             if (ll-w>=0) and (w-maxl>=0)  then
    117               begin
    118                 if bo[y]=0 then
    119                   begin
    120                     bo[y]:=1;
    121                     if v[y]=0 then
    122                       begin
    123                         t:=t+1;
    124                         list[t]:=y;
    125                         v[y]:=1;
    126                       end;
    127                   end;
    128               end;
    129             j:=next;
    130           end;
    131       end;
    132     v[list[h]]:=0;
    133   until h=t;
    134   if bo[zz]=1 then exit(true)
    135               else exit(false);
    136 end;
    137 
    138 procedure main;
    139 var
    140   l,r,mid:longint;
    141 begin
    142   l:=0; r:=maxlongint div 30;
    143   while l<=r do
    144     begin
    145       mid:=(l+r) div 2;
    146       if bfs1(mid) then
    147         begin
    148           maxl:=mid; l:=mid+1;
    149         end else r:=mid-1;
    150     end;
    151   l:=0; r:=maxlongint div 30;
    152   while l<=r do
    153     begin
    154       mid:=(l+r) div 2;
    155       if bfs2(mid) then
    156         begin
    157           maxr:=mid; r:=mid-1;
    158         end else l:=mid+1;
    159     end;
    160   writeln(maxl,' ',maxr);
    161 end;
    162 
    163 begin
    164   assign(input,'trip.in');
    165   assign(output,'trip.out');
    166   reseT(input);
    167   rewrite(output);
    168   init;
    169   main;
    170   close(input);
    171   close(output);
    172 end.
  • 相关阅读:
    数组排序去重
    js打印页面添加分页
    使用navicate可视化工具连接mysql数据库错误
    php_smarty模板引擎与.NET_VTemplate模板引擎对比
    JoshChen判断是否微信内置浏览器访问【转载】
    JoshChen毕业设计分享之班级网站-ASP.NET
    JoshChen防止前台恶意修改数据
    JoshChen安卓开发学习,从零开始(2)
    JoshChen安卓开发学习,从零开始(1)
    JoshChen模式笔记之php单例模式
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9445166.html
Copyright © 2011-2022 走看看