最短 路径问题

继续上一次的  拯救007    再上一个问题的基础上  告诉他  能跳上岸的最短步骤.

最短路径     最短的路  最便宜的路  都是最短路径

最短路径的衡量是    其权重大小 权重可以是 时间  路程 花费  站点数  

最短路径问题的抽象

  在网络中,求两个不同定点之间的所有路径中,边的权值之和最小的那一条路径.

      这条路径就是两点之间的最短路径(Shortest)

      第一个定点为源点(Source)

      最后一个顶点为终点(Destination)

问题分类

   单源最短路径问题:从某固定源点出发,求其到所有其他顶点的最短路径.

      (有向)无权图

          按照递增(非递减)的顺序找出到各个项点的最短路

 有向无权图   的  单源路径最短问题的分析步骤就在上面的图里.

void FBS(Vertex S)  //传送过来 一个图
{
    visited[S]=ture;   //访问第一个节点               
    Enqueue(S,Q);       //将第一个 节点入队
    while(!IsEmpty[Q])   //队列不为空的话 继续进行
    {
        v=Dequeue(Q);   //让 节点出队  并且赋值  给v
        for(V的每个临接点W)  //用v的每个临接点轮番轰炸
        {
            if(!visited[W])  // 没有访问的话 
            {
                visited[W]=ture;  //访问一下  
                Enqueue(W,Q);    //并且 入队
            }
        }
    }
}
//dist[w]   =   s到w的最短距离.  //dist 可以起到  visited的作用
//dist[s]   =   0
//path[w]   =   s到w的路上经过的某顶点        
/*上面的    只是一个  广度优先搜索的   框架  在下面  加以改进 用于拯救007*/
void Unweighted(Vertex S)
{
    Enqueue(S,Q);              //对 第一个节点 入队
    while(!IsEmpty(Q))     //队列  不为空
    {
        V=Dequeue(Q);            //队列里最前面的  节点出队
        for(V的每个临接点 W)         //
        {
            if(dist[w]==-1)     // 默认的是  距离为 -1  如果是-1的话 就代表 没有 到过这个节点
            {
                dist[w]=dist[v]+1;  //这个节点等于上一个节点的距离+1
                path[w]=v;           //这个节点的上一个节点是v   w节点的上一个节点是v
                Enqueue(W,Q);   //  仔细观察   这里 和 for循环 那里.
            }
        }
    }
}

      (有向)有权图

   多源最短路径问题:求任意两点之间的最短路径.

从   v1到v6的最短路径是什么?

这个呢?     (以后不做考虑).                    ---负无穷

Dijkstra算法

  令S={源点S+已经确定了最短路径的顶点v1}

  对于任意一个未收录的顶点v,定义dist[v]为s到v的最短路径长度,但该路径仅经过S中的顶点.即路径{s->(vi∈s)->v}的最小长度

  若路径是按照递增(非递减)的顺序生成的则

        真正的最短路必须只经过S中的顶点.

        每次从未收录的顶点中选取一个dist最小的收录(贪心)

/*可能有思想原因,身体原因,或者这个算法 难理解   我是用了一天  现在 应该差不多知道了一点*/
void Dijkstra(Vertex s)
{ 
    while(1)
    {
        V=未收录的顶点中dist最小者  //和源点相邻的 是权  不相邻的是 正无穷
        if(这样的V不存在)
            break;
        collected[V]=ture;
        for(V的每个临接点W)
        {
            if(collect[W]==false&&dist[V]+E<v,w> < dist[W])
            {
                dist[W]=dist[V]+E<v,w>;
                path[W]=V;
            }
        }
    }
}
//根据图 自己做了一半模拟之后 顿感666

 下面附上   上面伪代码里面      " V=未收录的顶点中dist最小者 "的实现方法.

//这里给出两种   实现上述功能的算法,但是相比之下  还是使用传统的算法 好一点简单省力   程序短.
方法1 :直接扫描所有未收录顶点 – O( |V| )  T = O( |V| 2 + |E| )  方法2 :将dist 存在最小堆中 – O( log|V| )  更新dist[w]值 的值 – O( log|V| )  T = O( |V| log|V| + |E| log|V| ) = O( |E| log|V| )

-------------被 单源最短路径坑了半天---下面开始多元路径问题了----------------------

//多元最短路算法  --可以用单源最短路径算法 每个节点 都调用一次
//这样的话时间复杂度是   V^3 + E *V  
//所谓的Floyd算法  时间复杂度是   V^3  鉴于这种 操蛋的情况  还是了解一下算了
//到时候不会用.
原文地址:https://www.cnblogs.com/A-FM/p/5153263.html