Dijkstra算法——超~~详细!!

Posted zjydeoneday

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dijkstra算法——超~~详细!!相关的知识,希望对你有一定的参考价值。

Dijkstra算法
_ ** 时隔多月,我又回来了!**_
今天下午久违的又学了会儿算法,又重新学习了一遍Dijkstra,这是第三次重新学习Dijkstra(*以前学的都忘完了>_<*).
废话先不bb,上代码。

#include<bits/stdc++.h>
using namespace std;
#define INF 9999999
#define M 1000
int d[M];
int p[M]={0};
int con[M][M];
int n,line;           //n点数,边数line 

struct node{
    char name;
}w[M];
void Dijkstra(int v,int *d,int p[],int con[M][M]) //初始点v 
{
    int vis[M];
    for(int i=1;i<=n;i++)        //第一步,确定与初始点v连接的点的路径 
    {
        d[i]=con[v][i];
        vis[i]=0;               //vis初始化 
        if(d[i]!=INF)
        p[i]=v;
    }
    d[v]=0;                     //对第一个点初始化 
    vis[v]=1;
    for(int i=1;i<=n;i++)       //第二布,两重循环 ,每次循环又分两步 。判断所有点 
    {
        int a=INF,id=v;
        for(int j=1;j<=n;j++) //1、找出该次循环中距离最小的点, 该点可能是一条新的路径 
        {
            if(d[j]<a && !vis[j])
            {
                a=d[j];       //a确定值 
                id=j;         //id确定点的下标 
            }
        }        
        vis[id]=1;              //已判断过 ,已经走过 
        for(int j=1;j<=n;j++)   //2、 从此时距离最短的点出发,更新与id相连的点的值,有两种情况 
        {                                     
            if(!vis[j] && con[id][j]<INF)  
            {
                int newdis=d[id]+con[id][j];
                if(newdis<d[j])         //根据 newdis与d[j]判断 
                {                     
                    d[j]=newdis;
                    p[j]=id;
                }    
            }
        }
    }
}
int idex(char a)
{
    for(int i=1;i<M;i++)
        if(w[i].name==a)
            return i;
}
void fun(int *p,char fist,char last)
{
    char x[M];
    int f=idex(fist),l=idex(last);
    cout<<""<<fist<<""<<last<<"的最短路径为:
";
    x[0]=last;
    int y=1;
    int t=p[l];
    while(t!=f)
    {
        x[y++]=w[t].name;
        t=p[t];
    }
    cout<<fist;
    for(int i=y-1;i>=0;i--)
    cout<<"->"<<x[i];
    cout<<"
";
}
int main()
{
    char a,b;
    int dis;
    cout << "************算法6.10 迪杰斯特拉算法**************
"; 
    cout<<"请输入总点数,总边数:";
    cin>>n>>line;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            con[i][j]=INF;
    for(int i=1;i<=n;i++)
    {
        cout<<"请输入第"<<i<<"个点:";
        cin>>w[i].name;
    }
    for(int i=1;i<=line;i++)
    {
        cout<<"请输入第"<<i<<"条边:";
        cin>>a>>b>>dis;
        int a1=idex(a),b1=idex(b);
        if(dis<INF)
        {
            con[a1][b1]=dis;
            con[b1][a1]=dis;
        }
    }
    
    cout << "*****无向网G创建完成!*****
" ;
    for(int i=1;i<=n;i++)
        d[i]=INF;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(con[i][j]==INF)
            cout<<"";
            else
            cout<<con[i][j]<<" ";
        }
        printf("
");
    }
    cout<<"请输入起点和终点:";
    cin>>a>>b;
    Dijkstra(idex(a), d, p, con);
    cout << a<<"到最后"<<b<<"的最短路径长度为: " << d[idex(b)] <<"
";    
    fun(p,a,b); 
    return 0;
} 

 

这次学习总结了Dijkstra算法模板函数的几个主要步骤,因为这个函数没有用到递归,只
用了两个循环,因此可以分为从上到下的两步。
Dijkstra算法模板函数主要有两步:
一、
确定与初始点v连接的点的路径 ,检查所有与初始点连接的点并更新他们的d[i]值。
二、
一个二重嵌套循环,每次for循环里又分两步:
1、
找出此次循环中(d[i]中)距离值最小的,并分别用id,a记录该点对应的下标与d[i].
2、
以这个点(id)为初始点,更新所有与该点相连通的点(d数组).
重复第二步。
**以上。**

以上是关于Dijkstra算法——超~~详细!!的主要内容,如果未能解决你的问题,请参考以下文章

图论-最短路Dijkstra算法详解超详 有图解

Dijkstra算法详细(单源最短路径算法)

LeetCode 260 只出现一次的数字(超详细)

最短路径-Dijkstra算法(转载)

漫画:Dijkstra 算法的优化

数据挖掘经典算法之K-邻近算法(超详细附代码)