迪杰斯特拉(Dijkstra)算法

迪杰斯特拉(Dijkstra)算法

迪杰斯特拉算法求得是原点到各个点之间的距离,不是任意两点间的距离,各点之间的权值不能为负,否则算法不适用

 思路:数组dis:表示起点到各点的距离,maps表示各个点之间的距离,如果不相通初始化为无穷,vis表示从起点到该点的距离是否确定

将起点写入相应的数组中,dis = 0,vis = 1

然后开始找与起点相连的最短的那个点,则该店就算已经确定,确定之后就要修改相应的数据:

所有点中,只要没有没有确定距离的(vis=0)点,都需要进行判断,从起点直接到该点和经过刚才确定的点到该点,哪个更近,存储在dis中

上述循环一次只能确定一个点,所有再进行上次循环直到n-1次;

之后dis表示的就是从起点到个点的最短距离

上代码:注意初始化时,图是无向图还是有向图

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

//重点!!!!!
//写整个程序时一定要map[i][j] = map[j][i] 初始化!!!!!
const int INF=0x3f3f3f3f;
const int maxn=1005;

int dis[maxn],maps[maxn][maxn],n;//n 点的个数
bool vis[maxn];

void Init(){
    for(int i = 1;i <= n;i++){
        dis[i] = INF;
        vis[i] = false;
        for(int j = 1;j <= i; j++)
            i == j ? maps[i][j] = 0 : maps[i][j] = maps[j][i] = INF;
    }
}

void Dijkstra(int s)//s表示起始点
{
    /*for(int i = 1; i <= n; i++)
        dis[i] = map[s][i];
    vis[s] = true;
    以上三行为一种Dijkstra 起始方式
    另一种:  (替换以上三句即可)*/
    dis[s] = 0;

    for(int i=1;i<=n;i++)
    {
        int p=-1,minn=INF;//p记录下一个最短距离的点
        for(int j=1;j<=n;j++)
        {
            if(!vis[j]&&dis[j]<minn)//j点未确定,且s->j的距离比minn小
            {
                minn=dis[j];
                p=j;
            }
        }//此时p就是已经确定的距离此时的点最短的点
        vis[p]=1;//确定

        for(int j=1;j<=n;j++)
        {
            if(!vis[j])
            {
                dis[j]=min(dis[j],dis[p]+maps[p][j]);
            }
        }
    }
}
//从1开始
int main()
{
    int m;
    cin>>n>>m;
    Init();
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        maps[a][b] = c;
    }
    Dijkstra(1);
    return 0;
}

 

posted @ 2020-03-03 22:52  精神小伙儿  阅读(645)  评论(0编辑  收藏  举报