zoukankan      html  css  js  c++  java
  • 最短路算法之 Dijkstra算法

      Dijkstra算法

         Dijkstra算法是典型最短路算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。

         Dijkstra算法是用来求任意两个顶点之间的最短路径。在该算法中,我们用邻接矩阵来存储图。在该程序中设置一个二维数组来存储任意两个顶点之间的边的权值。可以将任意一个图的信息通过键盘输入,让后在输入要查找的两个顶点,程序可以自动求出这两个顶点之间的最短路径。

    算法思想 

        s为源,Map[u,v] 为点u 和v 之间的边的长度,结果保存在 dis[];

        初始化:源的距离dis[s]设为0,其他的点距离设为无穷大,同时把所有的点状态设为没有扩展过。

    循环n-1次:

        1. 利用标记变量数组 在没有扩展过的点中取一距离最小的点u,并将其状态设为已扩展。

         2. 对于每个与u相邻的点v,如果dis[u] + Map[u,v]  <  dis[v],那么把dist[v]更新成更短的距离dis[u] + Map[u,v] 。此时到点v的最短路径上,前一个节点即为u。

    结束:此时对于任意的u,dist[u]就是s到u的距离。

    附 Hdu 2544 最短路

    做题思想

    建立一个Map的二维数组 里面的初始值改为一个INF(大数) 把从A到B 的路径长度储存进去

    建立一个Dis 的数组  储存Map[ s ][ 0 →n ]里的数据  循环N-1次 每次标记一个dis中最小的标号 并用

    if(!flag[i] && dis[i]>dis[t] + Map[t][i]) 该标号更新Dis 数组

    更新过后 dis[ x ] 即为源点S的到x 的最短距离

    代码

    #include<stdio.h>    // Dijkstra 算法
    #include<iostream>
    #include<string.h>
    #define INF 10000000
    using namespace std;
    int Map[101][101],dis[110];
    int n ,m;
    void Dijkstra()
    {
        int i,j,D = 0;
        bool flag[110];
        memset(flag,0,sizeof(flag));    //标记数组
        for(i=1; i<=n; i++)
            dis[i]=Map[1][i];           //与1处的距离  每一个i代表自身与1的距离
        for(i=1; i<n; i++)               //每次循环标记一个点   一共标记n-1个点
        {
            int temp = INF;
            for(j=1; j<=n; j++)       //找出dis数组中的最小的那个值 位置用D记录下来
                if(!flag[j]&&dis[j]<temp)
                {
                    temp = dis[j];
                    D = j;
                }
            flag[D] = 1;              //把该点标记
            for(j=1; j<=n; j++)       //更新dis数组   以D
            {
                if(!flag[j]&&dis[j] > Map[D][j]+dis[D])
                    dis[j] = Map[D][j]+dis[D];
            }
        }
    }
    int main()
    {
        int i,j,x,y,z;
        while(scanf("%d %d",&n,&m)!=EOF&&(m||n))
        {
            for(i=0; i<101; i++) {     //地图清空初始化为一个大数
                for(j=0; j<101; j++)
                    Map[i][j] = INF;
            Map[i][i]=0;
            }
            for(i=1; i<=m; i++)
            {
                cin >> x >> y >> z;      //输入
                if(Map[x][y] > z)         //如果再次输入的 比之前的小,覆盖
                    Map[x][y]=Map[y][x] = z;
            }
            Dijkstra();
            printf("%d
    ",dis[n]);      //全部循环过后,dis【n】的值即为从1到n 的距离;
        }
        return 0;
    }

    附:

    ACM假期集训感悟:

         一转眼半个月过去了,上午听师哥讲算法,看书;下午刷题,总结;

       别人都说我们程序员苦,累;还有一个绰号 “屌丝程序猿”;

       可我并不这么认为,每天学习算法锻炼思维,刷题提高代码能力和逻辑思维

       在ACM训练中,最开心的时候就是花老长时间去改错,WA一遍又一遍,终于该出了最后一个BUG ,AC!

       心情就无比的舒畅,看窗外的树叶是那样的翠绿,天是那样的蔚蓝。

        在大学生活中能过的如此充实,有动力,有目标,朝着目标一步一步的走去, 是多么幸福的一件事

    在这里,送出我的一句话:

           整个世界填满不了十八岁男孩子的雄心和梦。

  • 相关阅读:
    pytest: error: unrecognized arguments: --html=report.html
    运行pytest报错“PytestUnknownMarkWarning: Unknown pytest.mark.***
    SQL启动代理服务-自动备份的前提
    SQL Server数据库每日自动备份作业操作步骤(转载)
    c#播放声音文件(转载)
    使用Office组件导出Excel表格
    四舍五入保留小数问题
    List数据集按对象某个属性排序
    C# 创建Windows Service(Windows服务)程序
    WebService下实现大数据量的传输(转载)
  • 原文地址:https://www.cnblogs.com/Both-wings/p/3872380.html
Copyright © 2011-2022 走看看