zoukankan      html  css  js  c++  java
  • 迪杰斯特拉(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;
    }

     运行结果如下:

     

  • 相关阅读:
    [luogu3393]逃离僵尸岛
    [BZOJ2818]GCD
    [SCOI2015]情报传递
    [NOIP2010]引水入城
    [luogu4315]月下“毛景树”
    「LibreOJ NOI Round #2」不等关系
    [HNOI2013]游走
    Yet Another Minimization Problem
    ZJOI2015 地震后的幻想乡
    [九省联考2018]一双木棋chess
  • 原文地址:https://www.cnblogs.com/denghui666/p/9413843.html
Copyright © 2011-2022 走看看