题目描述
天网恢恢,疏而不漏,经过上一次的抓捕,OI总部终于获取了怪盗的特征!现在,我们需要在基德再次来之前就把他的特征送到超级大牛的手上,可惜超级大牛不在总部,所以飞过海必须尽快把资料送到大牛家里。已知OI总部到大牛家中间有n-2个城城市,为了尽快达到目的地,飞过海通过水晶球了解到OI总部到大牛家的路线图,图上显示了n个城之间的连接距离。
可是飞过海很忙,需要请你来帮忙编写一个程序。
输入
输入文件中的第一行为一个整数n(n<=1000)。
第二行至第n+1行,每行有n个数。其中:第i+1行中表示第i个城市与其他城市之间的连接关系,0表示不连接,其它数字表示连接的距离。
输出
输出文件中的第一行为n个整数,表示所选的线路。
第二行中为一个数,表示最短距离。
样例输入
7
0 3 5 0 0 0 0
0 0 0 7 8 6 0
0 0 0 0 4 5 0
0 0 0 0 0 0 4
0 0 0 0 0 0 7
0 0 0 0 0 0 6
0 0 0 0 0 0 0
样例输出
1 2 4 7
14
TJ
这道题是一道经典的最短路问题,难点在于怎样记录路径。其实只要定一个数组,表示到达这个城市前,你在哪个城市。在做SPFA时,每更新一次最短路,就把这个数组也更新了,就可以解决这个问题。
BC
var
l,i,j,n,s:longint;
f,nl:array[0..1001,0..2000]of longint;
dis,qian,ans,q:array[0..10000000]of longint;
begin
assign(input,'city.in');reset(input);
assign(output,'city.out');rewrite(output);
readln(n);
for i:=1 to n do
for j:=1 to n do
begin
read(f[i,j]);
if f[i,j]>0 then
begin
inc(nl[i,0]);
inc(nl[j,0]);
nl[i,nl[i,0]]:=j;
nl[j,nl[j,0]]:=i;
end;
end;
for i:=1 to n do dis[i]:=maxlongint;
dis[1]:=0;
l:=1;
q[l]:=1;
q[0]:=1;
repeat
s:=q[l];
for i:=1 to nl[s,0] do
begin
if (dis[nl[s,i]]>dis[s]+f[s,nl[s,i]]) then
begin
inc(q[0]);
q[q[0]]:=nl[s,i];
dis[nl[s,i]]:=dis[s]+f[s,nl[s,i]];
qian[nl[s,i]]:=s;
end;
end;
inc(l);
until q[l]=0;
i:=n;
repeat
inc(ans[0]);
ans[ans[0]]:=i;
i:=qian[i];
until i=1;
inc(ans[0]);
ans[ans[0]]:=i;
for i:=ans[0] downto 1 do write(ans[i],' ');
writeln;
writeln(dis[n]);
close(input);close(output);
end.