洛谷 P1629 邮递员送信

题目

有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N。由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有M条道路,通过每条道路需要一定的时间。这个邮递员每次只能带一样东西。求送完这N-1样东西并且最终回到邮局最少需要多少时间。

题解

首先用Floyd肯定会超时,然后用Dij每个点求一遍也肯定会超时,因为这都是

n3

所以我们先用Dij求一次从起点到其他所有点的路径和,
然后把所有边反过来,再求一遍从起点到其他点的路径和(求从每个点回到起点的路径和,理解不了就画一下图)
O(n2)

代码

type
  arr=array[1..1000,1..1000]of longint;
var
  n,m,i,j,x,y,ans:longint;
  a,b:arr;
  d:array[1..1000]of longint;
  f:array[1..1000]of boolean;

procedure dij;
var
  i,j,u,min:longint;
begin
  fillchar(f,sizeof(f),true);
  fillchar(d,sizeof(d),$7f);
  for i:=2 to n do if f[i] then d[i]:=a[1,i];
  repeat
    u:=0;min:=d[1];
    for i:=2 to n do
      if f[i] and(d[i]<min) then
        begin
          min:=d[i];
          u:=i;
        end;
      if u>0 then
        begin
          f[u]:=false;
          ans:=ans+d[u];
          for i:=2 to n do
            if f[i] and(d[i]>d[u]+a[u,i]) then
              d[i]:=d[u]+a[u,i];
        end;
  until u=0;
end;

procedure dij2;
var
  i,j,u,min:longint;
begin
  fillchar(f,sizeof(f),true);
  fillchar(d,sizeof(d),$7f);
  for i:=2 to n do if f[i] then d[i]:=b[1,i];
  repeat
    u:=0;min:=d[1];
    for i:=2 to n do
      if f[i] and(d[i]<min) then
        begin
          min:=d[i];
          u:=i;
        end;
      if u>0 then
        begin
          f[u]:=false;
          ans:=ans+d[u];
          for i:=2 to n do
            if f[i] and(d[i]>d[u]+b[u,i]) then
              d[i]:=d[u]+b[u,i];
        end;
  until u=0;
end;

begin
  readln(n,m);
  fillchar(a,sizeof(a),$7f);
  fillchar(b,sizeof(b),$7f);
  for i:=1 to m do
    begin
      readln(x,y,j);
      if a[x,y]>j then a[x,y]:=j;
      if b[y,x]>j then b[y,x]:=j;
    end;
  dij;
  dij2;
  writeln(ans);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值