zoukankan      html  css  js  c++  java
  • 简单单源最短路径笔记QwQ

    推荐阅读:

    国家集训队论文2006 《最短路算法及其应用》 By 广东北江中学 余远铭 

    国家集训队论文2009 《迭代求解的神器——spfa算法的优化和应用》By 中山纪念中学 姜碧野

    以及   《算法导论》

    注意:以下模板题目是:P3371 luogu

     luoGu的模板题比较坑,因为相邻的两点间的边可能有3条以上,所以对于floyed和dijkstra从i到j的边如果有多条要取最短的那条,

    但是对于spfa和bellman-ford就不用啦 2333

    Floyed ——O(n^3)

    通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。——from 知乎 

    关键是枚举中间点

    伪代码:

    for k:= 1 to n do 
      for i:= 1 to n do 
         for j:= 1 to n do 
            f[i,j]:=min(f[i,j],f[i,k]+f[k,j]);

    巧妙的Floyd优化,删点那一题目——小X的最短路,从删光点开始往前推,每次增加一点,不能照搬Floyd,要分别以他为起点,终点,中转点来一次Floyd,复杂度大概O(N^3)

    还能用来判断点的连通性。

    Dijkstra  ——O(n^2)

    不能处理负边权!                                         

     图片来自维基百科   图片来自维基百科

    主要思想:

    初始化数组为maxlongint div 3;   c[i]表示起点到i点的最短距离

    从起点开始找,直到找了n-1个点

    每次找离当前点最近的蓝点【包括自己】,把它变白,以此为中转点更新与之相连的蓝点到起点的距离。

    使它到起点的距离不再是maxlongint div 3或者其他,所以下一个找的蓝点说不定就是它,如图点7

    图片来自《算法导论》

    模板:

    //纯dijkstra ,    Score: 70 MLE
    program shortest;
    var
      n,i,a,b,m,j,s,e,min,k,tmp:longint;
      x,y:array[1..500000] of longint;
      che:array[1..1000] of boolean;
      c:array[1..1000] of longint;
      f:array[1..1000,1..1000] of longint;
    begin
      readln(n,m,s);
      fillchar(f,sizeof(f),$5f);
    
      for i:= 1 to m do
      begin
        readln(x[i],y[i],tmp);//x表示边的左端点,y表示边的右端点
        if (f[x[i],y[i]]>0) and (f[x[i],y[i]]>tmp) then f[x[i],y[i]]:=tmp;
      end;
      for i:= 1 to n do c[i]:=f[s,i];
      c[s]:=0;
    
      for i:= 1 to n-1 do
        begin
          min:=maxlongint;  k:=0;
          for j:= 1 to n do
            if che[j]=false then
              if c[j]<min then
                begin
                  min:=c[j];
                  k:=j;
                end;
          if k=0 then break;
          che[k]:=true;
          for j:= 1 to n do
            if c[j]>f[k,j]+c[k] then c[j]:=f[k,j]+c[k];//如果要记录前驱要在这里的relax添加pre的记录
        end;
    
      for i:= 1 to n do if c[i]<>1600085855 then write(c[i],' ') else write('2147483647 ')
    
    end.

    Bellman-Ford——O(NE)

    无法处理负权回环

     思想

    每次都对M条边做一遍relax操作,必然会有至少一个蓝点turn white.

    假设最坏情况(relax),每次只有一个蓝点变白,那么我们至少要n次*m次的relax操作!

     模板

    //Score: 70   , DATE8-10: TLE
    program shortest;
    var
      n,i,a,b,m,j,s,e:longint;
      x,y:array[1..500000] of longint;
      w:array[1..500000] of longint;
      c:array[1..10000] of longint;
    
    procedure printf();
    begin
      for i:= 1 to n do
       if c[i]<>2139062143 then write(c[i],' ')
       else write('2147483647 ');
    end;
    
    procedure init();//初始化过程
    begin
      fillchar(c,sizeof(c),$7f);                 //这样会得到一个接近maxlongint的数——2147483647
       c[s]:=0;
    end;
    function bellman_ford:boolean;
    begin
      init;
      for i:= 1 to n do
        for j:= 1 to m do
           if c[y[j]]>c[x[j]]+w[j] then c[y[j]]:=c[x[j]]+w[j]; //relax,注意有无向
    
      {for j:= 1 to m do                          //判断负权回路
      if (c[y[j]]>c[x[j]]+w[j]) then exit(false);}//根据路径松弛性质,最短路径中的边的最短路径估计值在达到下限后不再会改变,除非出现负权回路
      exit(true);                                 //虽然该题不会有负权回路
    end;
    
    begin
      readln(n,m,s);
      for i:= 1 to m do
        readln(x[i],y[i],w[i]);//x表示边的左端点,y表示边的右端点
    
      if bellman_ford then printf
      else writeln('Impossible');               
    end.

     SPFA:

     其他

    以下内容来自《算法导论》第三版

    relax操作

    对最短路径的估计值的收紧【更新】并更新前驱

    《算法导论》第三版

    《迭代求解的神器——spfa算法的优化和应用》

    相关性质

    注意:为连接u和v的边的权值,即dis[v],表示从起点到v点的最短路径的估计值,表示s到v的最短路径长度,就是的下界

     P.S. 感觉似乎没有必要证明,想想就知道。。

    (1)反证法证明最短路径的子路径也是最短路径

    定理1 (最优子结构给定有向加权图G=(V,E),设P=<v1, v2,, vk>为从结点v1到结点vk的一条最短路径,对任意i,ji<=j<=k,设Pij=< vi, vi+1,, vj>为从vivjP的子路径,Pij是从vivj的一条最短路径。

    证明:我们把路径P分解为<v1,v2,,vi,vi+1,vj,vk>。则w(P)=w(P1i)+w(Pij)+w(Pjk)。现在假设从vivj存在一路径Pij,且w(Pij)<w(Pij),则将P中的路径Pij=(vi,vi+1,vj)替换成Pij,依然是从v1vk的一条路径,且其权值 w(P1i)+w(Pij)+w(Pjk)小于w(P),这与前提P是从v1vk的最短路径矛盾。(证毕)

    (2)三角不等式性质

    (3)上界性质:对于

    (4)非路径性质:没有路径(注意不是边)相连的点到起点的最短路径为∞

    (5)收敛性质:当达到下界时,任何relax操作都不会让它再发生变化

    (6)路径松弛性质:对最短路径中的第k条边保证

  • 相关阅读:
    在Centos7下源代码安装配置Nginx
    mysql5.7.21源码安装
    数据库设计三大范式
    电商项目中使用Redis实现秒杀功能
    PHP和Redis实现在高并发下的抢购及秒杀功能示例详解
    PHP面向对象(抽象类与抽象方法、接口的实现)
    php面向对象 封装继承多态 接口、重载、抽象类、最终类总结
    利用VHD虚拟文件加密自己的个人信息
    Chrome常用快捷键
    stl本子
  • 原文地址:https://www.cnblogs.com/bobble/p/6388405.html
Copyright © 2011-2022 走看看