• bzoj3575 [Hnoi2014]道路堵塞


    A国有N座城市,依次标为1到N。同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数。现在,A国交通部指定了一条从城市1到城市N的路径,并且保证这条路径的长度是所有从城市1到城市N的路径中最短的。不幸的是,因为从城市1到城市N旅行的人越来越多,这条由交通部指定的路径经常发生堵塞。现在A国想知道,这条路径中的任意一条道路无法通行时,由城市1到N的最短路径长度是多少。

    Input

    输入文件第一行是三个用空格分开的正整数N、M和L,分别表示城市数目、单向道路数目和交通部指定的最短路径包含多少条道路。
    按下来M行,每行三个用空格分开的整数a、b和c,表示存在一条由城市a到城市b的长度为c的单向道路。这M行的行号也是对应道路的编号,即其中第1行对应的道路编号为1,第2行对应的道路编号为2,…,第M行对应的道路编号为M。最后一行为L个用空格分开的整数sp(1)…,,sp(L),依次表示从城市1到城市N的由交通部指定的最短路径上的道路的编号。

    Output

    输出文件包含L行,每行为一个整数,第i行(i=1,2…,,L)的整数表示删去编号为sp(i)的道路后从城市1到城市N的最短路径长度。如果去掉后没有从城市1到城市N的路径,则输出一1。

    Sample Input

    4 5 2
    1 2 2
    1 3 2
    3 4 4
    3 2 1
    2 4 3
    1 5

    Sample Output

    6
    6

    HINT

    100%的数据满足2<N<100000,1<M<200000。所用道路长度大于0小于10000。

    数据已加强By Vfleaking

    这题我是看别人题解的,感觉复杂度很玄学。

    传送门:

    http://www.cnblogs.com/mmlz/p/4297696.html

    http://www.cnblogs.com/MashiroSky/p/6440116.html

     1 program road(input,output);
     2 const
     3   inf=1000000000;
     4 type
     5   etype=record
     6      t,w,next:longint;
     7   end;
     8 var
     9   a,b,c,d,g,q,dis:array[0..100010]of longint;
    10   h,p:array[0..1000000]of longint;
    11   inq,ing:array[0..100010]of boolean;
    12   e:array[0..200020]of etype;
    13   n,m,l,i,j,k,head,tail,t,x,y,z,cnt,tot:longint;
    14 procedure add(x,y,w:longint);
    15 begin
    16   e[i].t:=y;e[i].w:=w;e[i].next:=a[x];a[x]:=i;
    17 end;
    18 procedure swap(var a,b:longint);
    19 begin
    20    t:=a;a:=b;b:=t;
    21 end;
    22 procedure ins(x,y:longint);
    23 begin
    24    inc(tot);p[tot]:=x;h[tot]:=y;
    25    k:=tot;
    26    while (h[k]<h[k>>1]) and (k>1) do begin swap(h[k],h[k>>1]);swap(p[k],p[k>>1]);k:=k>>1; end;
    27 end;
    28 procedure del;
    29 begin
    30    p[1]:=p[tot];h[1]:=h[tot];dec(tot);
    31    k:=1;
    32    while true do
    33       begin
    34          if k+k>tot then break;
    35          if k+k=tot then
    36             begin
    37                if h[k+k]<h[k] then begin swap(h[k],h[k+k]);swap(p[k],p[k+k]); end;
    38                break;
    39             end;
    40          if (h[k]<=h[k+k]) and (h[k]<=h[k+k+1]) then break;
    41          if h[k+k]<h[k+k+1] then begin swap(h[k],h[k+k]);swap(p[k],p[k+k]);k:=k+k; end
    42          else begin swap(h[k],h[k+k+1]);swap(p[k],p[k+k+1]);k:=k+k+1; end;
    43       end;
    44 end;
    45 begin
    46    assign(input,'road.in');assign(output,'road.out');reset(input);rewrite(output);
    47    readln(n,m,l);
    48    fillchar(a,sizeof(a),0);
    49    for i:=1 to m do begin readln(x,y,z);add(x,y,z); end;
    50    fillchar(c,sizeof(c),0);c[1]:=1;
    51    for i:=1 to l do begin read(b[i]);c[e[b[i]].t]:=i+1; end;
    52    d[l+1]:=0;
    53    for i:=l downto 1 do d[i]:=d[i+1]+e[b[i]].w;
    54    dis[1]:=0;for i:=2 to n do dis[i]:=inf;
    55    fillchar(ing,sizeof(ing),false);
    56    fillchar(inq,sizeof(inq),false);
    57    b[0]:=0;e[0].t:=1;
    58    tot:=0;
    59    for i:=1 to l do
    60       begin
    61          head:=0;tail:=1;cnt:=0;q[1]:=e[b[i-1]].t;inq[q[1]]:=true;
    62          while head<>tail do
    63             begin
    64                inc(head);if head>100000 then head:=1;
    65                j:=a[q[head]];
    66                while j<>0 do
    67                   begin
    68                      if j<>b[i] then
    69                         begin
    70                            if dis[q[head]]+e[j].w<dis[e[j].t] then
    71                               begin
    72                                  dis[e[j].t]:=dis[q[head]]+e[j].w;
    73                                  if c[e[j].t]>=c[e[b[i]].t] then
    74                                     begin
    75                                        if not ing[e[j].t] then begin inc(cnt);g[cnt]:=e[j].t;ing[e[j].t]:=true; end;
    76                                     end
    77                                  else if not inq[e[j].t] then
    78                                     begin
    79                                        inc(tail);if tail>100000 then tail:=1;
    80                                        q[tail]:=e[j].t;inq[e[j].t]:=true;
    81                                     end;
    82                               end;
    83                         end;
    84                      j:=e[j].next;
    85                   end;
    86                inq[q[head]]:=false;
    87             end;
    88          for j:=1 to cnt do begin ins(c[g[j]],dis[g[j]]+d[c[g[j]]]);ing[g[j]]:=false; end;
    89          while (p[1]<c[e[b[i]].t]) and (tot>0) do del;
    90          if tot=0 then writeln(-1) else writeln(h[1]);
    91          dis[e[b[i]].t]:=dis[e[b[i-1]].t]+e[b[i]].w;
    92       end;
    93    close(input);close(output);
    94 end.
  • 相关阅读:
    mybatis 基于xml 配置的映射器
    【☆】素数打表--重要
    HDU--1084 What Is Your Grade?
    Bear and Three Balls
    【水题】HDU--1280 前m大的数
    HDU--1234 开门人和关门人
    HDU--1862 EXCEL排序
    HDU--1872 稳定排序
    聪明人的游戏,初中版 之目录
    SzNOI语法百题之1-10
  • 原文地址:https://www.cnblogs.com/Currier/p/6637693.html
Copyright © 2020-2023  润新知