[Vijos1082 丛林探险]

[题目来源]:vijos1082

[关键字]:最短路

[题目大意]:n个点m条边k的体力,每条边有一个长度和一个费体力值,能否从st走到ed,若能走到则最短走多少。

//=====================================================================================================

[分析]:就是用spfa求一遍最短路,只是在松弛时要加上一条:如果走此边不会耗费超过k的体力。至于图的存储结构,可以用邻接表或前向星。

[代码]:

View Code
  1 type
2 rec = record
3 x, y, d1, d2: longint;
4 end;
5 var
6 n, m, st, ed, limit: longint;
7 e: array[0..90000] of rec;
8 l, r: array[0..6000] of longint;
9 d1, d2: array[0..6000] of longint;
10 b: array[0..6000] of boolean;
11 q: array[0..500000] of longint;
12
13 procedure qs(l, r: longint);
14 var
15 i, j, mid, mid2: longint;
16 t: rec;
17 begin
18 i := l;
19 j := r;
20 mid := l+random(r-l+1);
21 mid2 := e[mid].y;
22 mid := e[mid].x;
23 repeat
24 while (e[i].x < mid) or ((e[i].x = mid) and (e[i].y < mid2)) do inc(i);
25 while (e[j].x > mid) or ((e[j].x = mid) and (e[j].y > mid2)) do dec(j);
26 if i <= j then
27 begin
28 t := e[i];
29 e[i] := e[j];
30 e[j] := t;
31 inc(i);
32 dec(j);
33 end;
34 until i > j;
35 if l < j then qs(l,j);
36 if i < r then qs(i,r);
37 end;
38
39 procedure init;
40 var
41 i, x, t: longint;
42 begin
43 readln(n,m);
44 t := 0;
45 for i := 1 to m do
46 begin
47 readln(e[i].x,e[i].y,e[i].d1,e[i].d2);
48 inc(t);
49 e[m+t].x := e[i].y;
50 e[m+t].y := e[i].x;
51 e[m+t].d1 := e[i].d1;
52 e[m+t].d2 := e[i].d2;
53 end;
54 readln(st,ed);
55 readln(limit);
56 randomize;
57 qs(1,2*m);
58 for i := 1 to 2*m do
59 begin
60 x := e[i].x;
61 if l[x] = 0 then l[x] := i;
62 r[x] := i;
63 end;
64 //for i := 1 to n do writeln(l[i],'',r[i]);
65 end;
66
67 procedure spfa;
68 var
69 h, t, i, x: longint;
70 begin
71 h := 1;
72 t := 1;
73 q[1] := st;
74 fillchar(b,sizeof(b),false);
75 b[st] := true;
76 fillchar(d1,sizeof(d1),0);
77 d1[st] := 0;
78 fillchar(d2,sizeof(d2),100);
79 d2[st] := 0;
80 while h <= t do
81 begin
82 x := q[h];
83 for i := l[x] to r[x] do
84 if (d1[x]+e[i].d1 <= limit) and (d2[x]+e[i].d2 < d2[e[i].y]) then
85 begin
86 d2[e[i].y] := d2[x]+e[i].d2;
87 d1[e[i].y] := d1[x]+e[i].d1;
88 if not b[e[i].y] then
89 begin
90 inc(t);
91 q[t] := e[i].y;
92 b[e[i].y] := true;
93 end;
94 end;
95 b[x] := false;
96 inc(h);
97 end;
98 if d2[ed] <> d2[0] then writeln(d2[ed]) else writeln(-1);
99 end;
100
101 begin
102 assign(input,'d:\1.in');reset(input);
103 assign(output,'d:\1.out');rewrite(output);
104 init;
105 spfa;
106 close(input);
107 close(output);
108 end.



你可能感兴趣的:(OS)