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
1 2 2
1 3 2
3 4 4
3 2 1
2 4 3
1 5
Sample Output
6
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.