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.

 

posted @ 2017-03-28 23:59  Klaier  阅读(167)  评论(0编辑  收藏  举报