Description
有n个城市,编号为0到n-1。小B想从城市s到城市t。他们选择了一家航空公司,这家公司有m种航线,每种航线连接了两个不同的城市。看在小B是个妹子的份上,航空公司的老总给了小B一点优惠:小B可以免费在最多k种航线上搭乘飞机。问小B最小花费是多少。
Input
第一行三个整数n,m,k,分别表示城市数量,航线数量和免费搭乘的航线数量。
第二行两个整数s,t,表示起点和终点。
接下来m行,每行三个整数a.b.c,表示一种航线,即可以从a到b,也可以从b到a,花费为c。
Output
一行一个整数,表示最小花费。
Sample Input
5 6 1
0 4
0 1 5
1 2 5
2 3 5
3 4 5
2 3 3
0 2 100
Sample Output
8
Hint
对于前30%的数据,2<=n<=50,1<=m<=300,k=0;
对于前50%的数据,2<=n<=600,1<=m<=6000,0<=k<=1;
对于前100%的数据,2<=n<=10000,1<=m<=50000,0<=k<=10,c<=1000.
分析:
在spfa的距离d[i]加一维为d[i,j]为走到i,用了j次免费的答案。
代码:
const
MaxE=50002;
MaxV=100001*2;
type
rec=record
x,y,w,next:longint;
end;
var
n,m,c,i,x,y,w,o,ed,k,l:longint;
g:array [-1..Maxv] of rec;
ls:array [-1..Maxe] of longint;
v,list:array [-1..maxe] of longint;
d:array [-1..maxe,-1..10] of longint;
procedure spfa(first:longint;k:longint);
var
head,tail,t,i:longint;
begin
tail:=1; head:=0;
list[1]:=first;
for i:=1 to n do
d[i,k]:=maxlongint;
d[first,k]:=0;
v[first]:=1;
while tail<>head do
begin
head:=head mod maxe+1;
t:=ls[list[head]];
while t>0 do
with g[t] do
begin
if d[x,k]+w<d[y,k] then
begin
d[y,k]:=d[x,k]+w;
if v[y]=0 then
begin
v[y]:=1;
tail:=tail mod maxe+1;
list[tail]:=y;
end;
end;
if (d[x,k-1]<d[y,k]) and (k<>0) then
begin
d[y,k]:=d[x,k-1];
if v[y]=0 then
begin
v[y]:=1;
tail:=tail mod maxe+1;
list[tail]:=y;
end;
end;
t:=next;
end;
v[list[head]]:=0;
end;
end;
procedure add(x,y,w:longint);
begin
inc(o);
g[o].x:=x;
g[o].y:=y;
g[o].w:=w;
g[o].next:=ls[x];
ls[x]:=o;
end;
begin
assign(input,'fly.in');
assign(output,'fly.out');
reset(input);
rewrite(output);
read(n,m,k);
read(c,ed);
for i:=1 to m do
begin
read(x,y,w);
add(x,y,w);
add(y,x,w);
end;
for l:=0 to k do
spfa(c,l);
writeln(d[ed,k]);
close(input);
close(output);
end.