首页 > 学院 > 开发设计 > 正文

洛谷 P1629 邮递员送信

2019-11-06 07:55:00
字体:
来源:转载
供稿:网友

题目题解代码

题目

有一个邮递员要送东西,邮局在节点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.
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表