码迷,mamicode.com
首页 > 其他好文 > 详细

Dijkstra

时间:2020-04-14 22:36:28      阅读:49      评论:0      收藏:0      [点我收藏+]

标签:ems   自己的   邻接   memset   data   就是   algorithm   http   cstring   

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 500;
int n, m, g[N][N], d[N];
bool st[N];
int dijkstra()
{
    memset(d, 0x3f, sizeof d);//两点之间和1到n-1个点之间的初始值都为+oo
    d[1] = 0;
    for(int i = 0;i<n;i++)
    {
        int t = -1;
        for(int j = 1;j<=n;j++)
            if(!st[j] && (t == -1 || d[t] > d[j]))
                t = j;
        st[t] = true;
        
        for(int j = 1; j <= n;j++)
            d[j] = min(d[j], d[t] + g[t][j]);
    }
    if(d[n] == 0x3f3f3f3f) return -1;
    
    return d[n];
}
int main()
{
    memset(g, 0x3f, sizeof g);
    cin>>n>>m;
    for(int i = 0; i < n; i++)
    {
        int a, b, c;
        cin>>a>>b>>c;
        g[a][b] = min(g[a][b], c);
    }
    cout<<dijkstra()<<endl;
}

起始点为1,1到自己的距离d[1] = 0; 走过的点就打好标记不再考虑了,st[t]  = true;

任意两点之间和1到n-1个点之间的初始值都为无穷大+oo,g[]和d[]
每次向后拓展的时候都选择当前最短的边:d[t] > d[j] t = j;
若后面的点更新有更小的距离,那么就进行更新:d[j] = min(d[j], d[t] + g[t][j]);
注意Dijkstra如果有n个点的话,那么就要循环n次,也就是说,n个点没有负权的图(可以有自环和重边),通过跑n次Dijkstra一定可以跑出1到其他n-1个点的最短距离。
为什么如果有负权边不能用Dijkstra呢?因为如果有负数环的话,每跑一次距离就变小一次。。。
1n5001≤n≤500,
1m1051≤m≤105,
图中涉及边长均不超过10000。

此题点数较少,变数较多称为稠密图。上面的邻接矩阵版本是朴素的裸Dijkstra算法。
但是如果数据范围是:

数据范围

1n,m1.5×1051≤n,m≤1.5×105,
图中涉及边长均不小于0,且不超过10000。

那么就是稀疏图,如果还是用上面的邻接矩阵的话,10^5 * 10 ^ 5会爆掉。

那么就要用堆优化版本的Dijkstra算法。

Dijkstra

标签:ems   自己的   邻接   memset   data   就是   algorithm   http   cstring   

原文地址:https://www.cnblogs.com/longxue1991/p/12701553.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!