美文网首页
关于Dijkstra的小小研究

关于Dijkstra的小小研究

作者: 无敌未央様 | 来源:发表于2019-01-23 14:06 被阅读0次

    Dijkstra是用来解决图的最短路径问题的,核心思想我觉得是根据源点开始,在所有可能的路径中不断寻找最小权的路径,直到终点为止,从而形成图中两个点的最短路径。
    具体的算法思路可以参考我找到的视频:
    https://www.bilibili.com/video/av38254646?from=search&seid=5219412858608359008

    用邻接矩阵实现的图:

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    int map[110][110];//这就是map数组,存储图
    int dis[10010];//dis数组,存储估计值
    int book[10010];//book[i]代表这个点有没有被当做源点去搜索过,1为有,0为没有。这样就不会重复搜索了。
    int n,m;  //m是结点个数,n是行数,邻接矩阵行数就是列数
    void dijkstra(int u)//主函数,参数是源点编号
    {
        memset(dis,88,sizeof(dis));//把dis数组附最大值(88不是十进制的88,其实很大)
        int start=u;//先从源点搜索
        book[start]=1;//标记源点已经搜索过
    
        for(int i=0;i<n;i++)
            dis[i]=min(dis[i],map[start][i]);//先更新一遍
    
        for(int i=0;i<n-1;i++)
        {
            int minn=9999999;//这就是刚才所说的minn
    
            for(int j=0;j<n;j++)
                if(book[j]==0 && minn>dis[j])
                {
                    minn=dis[j];
                    start=j;//找到离源点最近的点,然后把编号记录下来,用于搜索。
                }
    
            book[start]=1;    
        
            for(int j=0;j<n;j++)
                dis[j]=min(dis[j],dis[start]+map[start][j]);//以新的点来更新dis。
    
        }
    }
    
    int main()
    {
        cin>>n>>m;
        memset(map,88,sizeof(map));
    
        for(int i=1;i<=m;i++)
        {
            int a,b,c;
            cin>>a>>b>>c;
            map[a][b]=c;
            map[b][a]=c;  //无向图矩阵应该是对称的
        }
    
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(i==j)
                    map[i][j]=0;
        int u;
        cin>>u;
        dijkstra(u);//以1为源点。
        for(int i=1;i<=n;i++)
            cout<<dis[i]<<" ";
    }
    
    

    用邻接表实现的图:

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    int value[10010],to[10010],next[10010];
    int head[10010],total;
    int book[10010];
    int dis[10010];
    int n,m;
    void adl(int a,int b,int c)
    {
        total++;
        to[total]=b;
        value[total]=c;
        next[total]=head[a];
        head[a]=total;
    }
    void dijkstra(int u)
    {
        memset(dis,88,sizeof(dis));
        memset(book,0,sizeof(book));
        dis[u]=0;
        for(int i=1;i<=n;i++)
        {
            int start=-1;
            for(int j=1;j<=n;j++)
                if(book[j]==0 && (dis[start]>dis[j] || start==-1))
                    start=j;
            book[start]=1;
            for(int e=head[start];e;e=next[e])
                dis[to[e]]=min(dis[to[e]],dis[start]+value[e]);
        }
    }
    int main()
    {
        cin>>n>>m;
        for(int i=1;i<=m;i++)
        {
            int a,b,c;
            cin>>a>>b>>c;
            adl(a,b,c);
         } 
         dijkstra(1);
         for(int i=1;i<=n;i++)
             cout<<dis[i]<<" ";
    }
    

    相关文章

      网友评论

          本文标题:关于Dijkstra的小小研究

          本文链接:https://www.haomeiwen.com/subject/vhbjjqtx.html