zoukankan      html  css  js  c++  java
  • 邮递员送信(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.  
  • 相关阅读:
    How To Build CyanogenMod Android for smartphone
    CentOS安装Code::Blocks
    How to Dual boot Multiple ROMs on Your Android SmartPhone (Upto Five Roms)?
    Audacious——Linux音乐播放器
    How to Dual Boot Multiple ROMs on Your Android Phone
    Everything You Need to Know About Rooting Your Android Phone
    How to Flash a ROM to Your Android Phone
    什么是NANDroid,如何加载NANDroid备份?
    Have you considered compiled a batman-adv.ko for android?
    BATMAN—Better Approach To Mobile Adhoc Networking (B.A.T.M.A.N.)
  • 原文地址:https://www.cnblogs.com/PengBoLiuXu/p/4550996.html
Copyright © 2011-2022 走看看