最短路径——Dijkstra算法

当你看到这篇文章时,我想你是想要实现最短路径了,至于什么是最短路径应该都知道了吧。那下面就直接从最短路径的迪杰斯特拉算法讲起吧。

的Dijkstra算法用于求单源点最短路径问题(即一个点到其余各点的最短路径),其基本思想如下:

设置一个集合小号存放已经找到最短路径的顶点,S的初始状态只包含V0,对六属于VS(V是全体顶点,VS英文的相对补集),假设从源点V到六的有向边为最短路径(初始化状态)。

以后每求得一条最短路径V,...,VK,就将VK加入集合小号中,并将路径V,...,VK加入集合小号中,并将路径V,...,VK,VK与原来的假设比较,取路径长度较小者为当前最短路径,重复上述过程,直到上述过程,直到集合V中全部顶点加入到集合小号中。


存储结构:

图的存储结构:邻接矩阵

辅助数组DIST [N]:元素DIST [I]表示当前所找到的从源点V到终点六的最短路径长度

   且需要不断更新,dist [i] = min {dist [i],dist [k] + arc [k] [i]} 0 <= i <= n-1

辅助数组路径[I]:这是一个字符串串,存路径


伪代码:

初始化数组dist,path,和s;

2.虽然(S中的元素个数<n)个

  2.1在dist [n]中求最小值,其编号为j

  2.2输出dist [j]和path [j];

  2.3修改数组dist和path;

  2.4将顶点j添加到数组s中


代码实现

#include <iostream>
#include <string>
#include <sstream>
#define MaxSize 100
#define INF 0x3f3f3f3f


using namespace std;




字符串路径[MaxSize];
int dist [MaxSize];
int s [MaxSize];


//将int型装换成String型
字符串Int_to_String(int n)
{
    ostringstream stream;
    流<< N; // n为int类型
    return stream.str();
}


//图的存储结构
struct Graph
{
    string vertex [MaxSize];
    int arc [MaxSize] [MaxSize];
    int vertexNum;
    int arcNum;
} G;


//核心算法
void dijkstra(struct Graph G,int v)
{
    int i,j,k,n,e,num = 0;


    N = G.vertexNum; //赋值,方便后面运用
    E = G.arcNum;


    //初始化dist和path数组
    for(i = 0; i <n; i ++)
    {
        dist [i] = G.arc [v] [i]; //             赋值边缘
        if(v!= i)
        {
if(dist [i]!= INF)//连通赋两点位置,不连通设为空串
                path [i] = G.vertex [v] + G .vertex [I];
            else
                path [i] =“”;
        }
        else
            path [i] =“”;
    }




    //






初始化s //先将v入集合s,并标记
    s [num] = v;
    DIST [V] = 0; //该标志为当前位置的数据已入集合s
    num ++; //一定要注意这个顺序,要不用是s [0],和num = 1也可以


    while(num <n)//当所有顶点都入集合了停止循环,即入集合数等于顶点数
    {
        DIST [MAXSIZE-1] = INF; //在此处注意,出现过BUG,原因是数据结构书上的J = 0不行,因为书上0是没设数据的,即把它看做无穷大
        //在DIST中求最小值,其编号为j //而我的代码dist [0]是有数据的
        for(i = 0,j = MaxSize-1; i <n; i ++)
        {
            if(dist [i] <dist [j] && dist [i] != 0)// dist [i]!= 0一次要写上
            {
                j = i;
            }
        }


        //输出j的数据
        cout <<“路径:”<< path [j] <<“距离之和:”<< dist [j] << endl;
        S [NUM ++] = j的; ∥焦位置入集合


        //更新DIST与路径数组
        为(I = 0; I <N;我++)
        {
            //只需对刚加入集合的Ĵ更新即可
            如果(DIST [I]> DIST [j]的+ G。

                DIST [I] = DIST [J] + G.arc [j]的[I];
                路径[I] =路径[J] + G.vertex [I];
            }
        }
        dist [j] = 0; //标志点j已入集合
    }


}




int main()
{
    int i,j,k,w;
    //初始化图G
    cout <<“请依次输入图的顶点数,边数和各边的三个数据”<< endl;
    CIN >> G.vertexNum >> G.arcNum;
    对于(
        j = 0; j <G.vertexNum; j ++)
        {
            G.arc [i] [j] = INF; 对于(i = 0; i <G.vertexNum; i ++)
            if(i == j)
                G.arc [i] [j] = 0;
        }




    for(i = 0; i <G.vertexNum; i ++)
    {
        G.vertex [i] =“v”+ Int_to_String(i)+“”;
    }


    for(i = 0; i <G.arcNum; i ++)
    {
        cin >> j >> k >> w;
        G.arc [J] [K] = W; //有向图
    }


    dijkstra(G,0);


    返回0;

}


测试数据:

输入:

4 8
0 1 2
1 2 3
0 2 6
2 0 7
0 3 4
3 0 5
2 3 7
3 2 12


输出:
路径:v0 v1距离之和:2
路径:v0 v3距离之和:4
路径:v0 v1 V2距离之和:5

* /


涉及到的INT类型转换成类请自行串百度


猜你喜欢

转载自blog.csdn.net/hitmi_/article/details/80777955