Description
Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格。Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?
数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数。 第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。 接下来有m行,每行三个整数,a,b,c,表示存在一种航线,能从城市a到达城市b,或从城市b到达城市a,价格为c。(0<=a,b<=n,a与b不相等,0<=c<=1000)
Output
只有一行,包含一个整数,为最少花费。
分析
一个分层图。
设f[i,j]为到达i点用了j次免费的最短路。
ps:要把spfa的队列开大一些(8000000+)或者打循环队列。
代码
const
maxn=
20000;
maxe=
400000;
type
arr=
record
x,y:longint;
w:longint;
next:longint;
end;
var
n,m,nm,num:longint;
s,t:longint;
edge:
array[
0..maxe]
of arr;
ls:
array[
0..maxn]
of longint;
f:
array[
0..maxn,
0..
100]
of longint;
queue:
array[
0..maxe*
20,
1..
2]
of longint;
status:
array[
0..maxn,
0..
100]
of longint;
procedure add(x,y,w:longint);
begin
num:=num+
1;
edge[num].x:=x;
edge[num].y:=y;
edge[num].w:=w;
edge[num].next:=ls[x];
ls[x]:=num;
num:=num+
1;
edge[num].x:=y;
edge[num].y:=x;
edge[num].w:=w;
edge[num].next:=ls[y];
ls[y]:=num;
end;
procedure init;
var
i:longint;
x,y,w:longint;
begin
readln(n,m,nm);
readln(s,t);
num:=
0;
for i:=
1 to m
do
begin
readln(x,y,w);
add(x,y,w);
end;
end;
procedure spfa;
var
i,j,k:longint;
head,tail:longint;
begin
fillchar(f,sizeof(f),$
7f);
head:=
0; tail:=
1;
queue[
1][
1]:=s;
queue[
1][
2]:=
0;
f[s][
0]:=
0;
status[s][
0]:=
1;
repeat
head:=head+
1;
i:=ls[queue[head][
1]];
while i<>
0 do
begin
with edge[i]
do
begin
j:=queue[head][
2];
if f[x,j]+w<f[y,j]
then
begin
f[y,j]:=f[x,j]+w;
if status[y][j]=
0
then
begin
tail:=tail+
1;
queue[tail][
1]:=y;
queue[tail][
2]:=j;
status[y][j]:=
1;
end;
end;
if j<nm
then
if f[x,j]<f[y,j+
1]
then
begin
f[y,j+
1]:=f[x,j];
if status[y][j+
1]=
0
then
begin
tail:=tail+
1;
queue[tail][
1]:=y;
queue[tail][
2]:=j+
1;
status[y][j+
1]:=
1;
end;
end;
i:=next;
end;
end;
status[queue[head][
1]][queue[head][
2]]:=
0;
until head=tail;
end;
procedure main;
var
i,j,k:longint;
ans:longint;
begin
spfa;
ans:=maxlongint;
for i:=
0 to nm
do
begin
if ans>f[t,i]
then ans:=f[t,i];
end;
writeln(ans);
end;
begin
init;
main;
end.
转载请注明原文地址: https://ju.6miu.com/read-1305550.html