• 邮递员送信(luogu 1629)题解


    【问题描述】

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

    【样例输入】

        5 10
        2 3 5
        1 5 5
        3 5 6
        1 2 8
        1 3 8
        5 3 4
        4 1 8
        4 5 3
        3 5 6
        5 4 2

    【样例输出】

        83

    【解题思路】

        看到这题……这不明摆着赤裸裸的最短路嘛,而且还要往返走,还是单向的,n<=1000,还用说什么?邻接矩阵+floyed搞起啊!然而……交上OJ后发现,仅仅AC了4个点……TLE6个……算了算复杂度,嗯……不错,最大可以到O(10^9)不爆才怪了……于是换一种思路……那么只能求单源最短路了,怎么求呢?两边dijkstra一边算过去的,一边算回来的……然后顺便注意一下重边,于是AC了……

        下面我们来总结一下求最短路的方法,求多源最短路……不用说,只能floyed,如果数据给大了的话肯定就是你想错了,比如今天这道题……由一点出发回到同一点的题可以看做单源最短路,如果没有负权边的话能用dijkstra尽量用dijkstra,(自我感觉dijkstra最好写……)当然愿意写SPFA是最佳选择,SPFA的时间复杂度是最低的。然后,对于存储图的问题,能用邻接矩阵尽量用邻接矩阵,邻接矩阵比邻接表还是方便许多的,(便于debug,便于观察),如果实在不行的话那就只能用邻接表了,愿意用邻接表的用邻接表也可以。(自我感觉不愿意去写……)

    【代码实现】

     1 var a:array[-1..1010,-1..1010] of longint;  
     2     i,j,n,m,u,v,w,ans,k:longint;  
     3     f:array[-1..1010] of boolean;  
     4     s1,s2:array[-1..1010] of longint;  
     5 procedure dijkstra;  
     6 var i,j,min,pos:longint;  
     7 begin  
     8  f[1]:=true;  
     9  for i:=2 to n do  
    10   begin  
    11    min:=maxlongint;  
    12    pos:=-1;  
    13    for j:=1 to n do  
    14     if not(f[j])and(s1[j]<min) then  
    15      begin  
    16       min:=s1[j];  
    17       pos:=j;  
    18      end;  
    19    if pos=-1 then  
    20     break;  
    21    f[pos]:=true;  
    22    for j:=1 to n do  
    23     if not(f[j])and(s1[pos]+a[pos,j]<s1[j]) then  
    24      s1[j]:=s1[pos]+a[pos,j];  
    25   end;  
    26 end;  
    27 procedure dijkstra1;  
    28 var i,j,min,pos:longint;  
    29 begin  
    30  f[1]:=true;  
    31  for i:=2 to n do  
    32   begin  
    33    min:=maxlongint;  
    34    pos:=-1;  
    35    for j:=1 to n do  
    36     if not(f[j])and(s2[j]<min) then  
    37      begin  
    38       min:=s2[j];  
    39       pos:=j;  
    40      end;  
    41    if pos=-1 then  
    42     break;  
    43    f[pos]:=true;  
    44    for j:=1 to n do  
    45     if not(f[j])and(s2[pos]+a[j,pos]<s2[j]) then  
    46      s2[j]:=s2[pos]+a[j,pos];  
    47   end;  
    48 end;  
    49 begin  
    50  readln(n,m);  
    51  for i:=1 to n do  
    52   for j:=1 to n do  
    53    a[i,j]:=maxint+100000;  
    54  for i:=2 to n do  
    55   begin  
    56    s1[i]:=maxint+100000;  
    57    s2[i]:=maxint+100000;  
    58   end;  
    59  for i:=1 to m do  
    60   begin  
    61    readln(u,v,w);  
    62    if w<a[u,v] then  
    63     a[u,v]:=w;  
    64    if (u=1)and(w<s1[v]) then  
    65     s1[v]:=w;  
    66    if (v=1)and(w<s2[u]) then  
    67     s2[u]:=w;  
    68   end;  
    69  dijkstra;  
    70  fillchar(f,sizeof(f),false);  
    71  dijkstra1;  
    72  for i:=2 to n do  
    73   ans:=ans+s1[i]+s2[i];  
    74  writeln(ans);  
    75 end.  
  • 相关阅读:
    bzoj5328: [Sdoi2018]物理实验
    HDU
    bzoj4820: [Sdoi2017]硬币游戏
    bzoj4600: [Sdoi2016]硬币游戏
    阿里云配置防火墙规则
    博客园 添加 Live 2D 模型
    R语言做逻辑回归
    R语言错误的提示(中英文翻译)
    用随机森林分类
    python 切换虚拟环境
  • 原文地址:https://www.cnblogs.com/PengBoLiuXu/p/4550996.html
Copyright © 2020-2023  润新知