迪杰斯特拉(Dijkstra)最短路径算法

回顾算法思路:

该算法用于求指定顶点A到其余每个顶点的最短路径;

将顶点分为两部分S、U,S部分是已经确定最短路径的点,另一部分U是尚未确定最短路径的点,

确保目前状态X的所有路径是从集合S到U某一点的最短路径(即路径只有终点在U中,其余顶点均在S中;

1、在所有路径中选取最短的路径所对应的顶点加入到S中(该条路径已经是确定的最短路径;

2、由于S中加入了一个顶点B,更新其他路径以达到状态X

循环1、2,确保所有的点都已加入S,结束;

#include<iostream>
#include<cstdlib>
#include<string>
using namespace std;

struct Dis {
    string path;//存储路径
    int value;//存储路径的值
    bool visit;//是否加入S中
    Dis() {//构造函数
        visit = "false";
        value = INT_MAX;
        path = "";
    }
};

struct Graph_DG {
    int vexnum;//顶点的数量
    int arcnum;//边的数量
    int **a;//存储图即每对顶点的权重
    Dis  *dis;
};

int main()
{
    cout << "本算法计算的是从无向图中一个指定点到其他任何一点"<<
        "的最短距离,以及对应的路径" << endl;
    Graph_DG DG;
    /*创建图*/
    cout << "请输入顶点数和边数:";
    cin >> DG.vexnum >> DG.arcnum;
    DG.a = new int *[DG.vexnum];
    for (int i = 0; i < DG.vexnum; i++)
    {
        DG.a[i] = new int[DG.vexnum];
        for (int j = 0; j < DG.vexnum; j++)
        {
            DG.a[i][j] = INT_MAX;
            if (i == j)
                DG.a[i][j] = 0;
        }
    }

    cout << "请输入每条边的起始点,终点和对应的权值" << endl;
    for (int i = 0; i < DG.arcnum; i++)
    {
        int x, y;
        cin >> x >> y;
        cin >> DG.a[x][y];
        DG.a[y][x] = DG.a[x][y];
    }

    int start;
    cout << "请输入该指定点:";
    cin >> start;
    DG.dis = new Dis[DG.vexnum];
    
    for (int i = 0; i < DG.vexnum; i++)
    {
        DG.dis[i].value = DG.a[start][i];
        DG.dis[i].visit = false;
        DG.dis[i].path = to_string(start) + "-->" + to_string(i);
    }
    //使用迪杰斯特拉算法
    int count = 1;
    DG.dis[start].visit = true;//将起点加入S中
    while (count < DG.vexnum)
    {
        int min = INT_MAX;
        int temp;
        for (int i = 0; i < DG.vexnum; i++)
        {
            if (DG.dis[i].value <= min && DG.dis[i].visit == false)
            {//只要有未加入的点,就找出距离最短的点加入
                min = DG.dis[i].value;
                temp = i;
            }
        }
        count++;
        DG.dis[temp].visit = true;

        //更新距离
        for (int i = 0; i < DG.vexnum ; i++)
        {
            if (DG.dis[i].visit == false)
            {
                if (DG.a[temp][i] < INT_MAX && DG.dis[i].value < INT_MAX && DG.dis[temp].value + DG.a[temp][i] < DG.dis[i].value)
                {
                    DG.dis[i].path = DG.dis[temp].path + "-->" + to_string(i);
                    DG.dis[i].value = DG.dis[temp].value + DG.a[temp][i];
                }
            }
        }
    }

    //打印输出
    for (int i = 0; i < DG.vexnum; i++)
    {
        if(DG.dis[i].value < INT_MAX)
            cout <<"距离:"<< DG.dis[i].value <<"最短路径:"<< " , "<< DG.dis[i].path << endl;
        else
            cout << "距离:" << "infinite , " << "最短路径:" << DG.dis[i].path << endl;
    }
    //非内部数据类型手动释放内存
    delete[] DG.dis;
    //二维数组释放内存的方法
    for (int i = 0; i < DG.vexnum; i++)
        delete[] DG.a[i];
    delete[] DG.a;
    system("pause");
    return 0;
}

 运行结果如下:

 

 

posted @ 2018-08-03 14:10  hui666  阅读(2342)  评论(1编辑  收藏  举报