Dijkstra算法(朴素版本&&堆优化版本)

朴素版本Dijkstra算法(求1->n的最短距离) O(n^2)

适合稠密图 用邻接矩阵存储
n为点数 m为边数

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

#define INF 0x3f3f3f3f
const int N = 5e2+2;
int g[N][N];
int d[N];
bool st[N];
int n, m;

int dijkstra()
{
    memset(d, 0x3f, sizeof d);
    d[0] = 0;
    for(int i = 1; i <= n; i++)
    {
        int t = -1;
        for(int j = 0; j < n; j++)
        {
            if(!st[j] && (t == -1 || d[j] < d[t])) t = j;
        }
        st[t] = true;
        for(int j = 0; j < n; j++)
            d[j] = min(d[j], d[t] + g[t][j]);
    }
    if(d[n-1] == INF) return -1;
    return d[n-1];
}

int main(void)
{
    memset(g, 0x3f, sizeof g);
    
    int a, b, c;
    scanf("%d%d", &n, &m);
    while (m -- )
    {
        scanf("%d%d%d", &a, &b, &c);
        g[a-1][b-1] = min(g[a-1][b-1], c);  // 重边
    }
    printf("%d", dijkstra());
}

堆优化版本Dijkstra算法(求1->n的最短距离) O(mlogn)

适合稠密图 用邻接矩阵存储

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>

using namespace std;

#define INF 0x3f3f3f3f
typedef pair<int, int> PII;
const int N = 1e5+2;
int h[N], e[N], w[N], ne[N], idx;
int d[N];
bool st[N];
int n, m;

void add(int a, int b, int c)
{
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}

int dijkstra()
{
    memset(d, 0x3f, sizeof d);
    d[1] = 0;
    priority_queue<PII, vector<PII>, greater<PII> > heap;
    heap.push({0, 1});  // {距离, 结点编号}
    while(!heap.empty())
    {
        PII t = heap.top(); heap.pop();
        if(st[t.second]) continue;
        st[t.second] = true;
        for(int i = h[t.second]; i != -1; i = ne[i])
        {
            int ind = e[i];
            if(d[ind] > t.first + w[i])
            {
                d[ind] = t.first + w[i];
                heap.push({d[ind], ind});
            }
        }
    }
    if(d[n] == INF) return -1;
    else return d[n];
}

int main(void)
{
    memset(h, -1, sizeof h);
    
    int a, b, c;
    scanf("%d%d", &n, &m);
    while (m -- )
    {
        scanf("%d%d%d", &a, &b, &c);
        add(a, b, c);
    }
    printf("%d", dijkstra());
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值