【普及模拟】城市连接

题目描述

天网恢恢,疏而不漏,经过上一次的抓捕,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.

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值