迪杰斯特拉最短路径

算法思想:每次从集合中找到一个未访问过的最短路径的点,然后根据改点来更新其他点的距离。

(1)朴素算法

适用场景:稠密图,边较多,适用邻接矩阵存储。

复制代码
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 510;
int g[N][N], dist[N]; // g为邻接矩阵, dist为距离
bool st[N];

int n, m;

int dijkstra()
{
    memset(dist, 0x3f, sizeof dist);
    dist[1] = 0;
    
    // 需要找n-1个点来更新距离
    for(int i=0;i<n-1;i++)
    {
        int t = -1;
        for(int j=1;j<=n;j++)
        {
            if(!st[j] && (t == -1 || dist[t] > dist[j])) t = j; // 找到不在集合中距离最小的点
        }
        // 更新距离
        for(int j=1;j<=n;j++)
        {
            dist[j] = min(dist[j], dist[t]+g[t][j]);
        }
        st[t] = true; // 放入集合中
    }
    return dist[n] == 0x3f3f3f3f? -1: dist[n];
}


int main()
{
    cin >> n >> m;
    memset(g, 0x3f, sizeof g); 
    for(int i=0;i<m;i++)
    {
        int a, b, w;
        cin >> a >> b >> w;
        g[a][b] = min(g[a][b], w); // 防止重边
    }
    
    int s = dijkstra();

    cout << s << endl;
    
    return 0;
}
复制代码

 (2)堆优化算法

适用场景:稀疏图,点较多边较少,适用邻接表存储。

复制代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>

using namespace std;

const int N = 150010;

typedef pair<int,int> PII;

int h[N], w[N], e[2*N], ne[2*N], idx;
int dist[N];
int n, m;
bool st[N];
priority_queue<PII, vector<PII>, greater<PII>> heap; // 优先队列

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

int dijkstra()
{
    memset(dist, 0x3f, sizeof dist);
    dist[1] = 0;
    heap.push({0, 1});
    
    while(heap.size())
    {
        auto p = heap.top();
        heap.pop();
        int d = p.first, v = p.second;
        if(st[v]) continue;
        st[v] = true;
        for(int i=h[v];i!=-1;i=ne[i])
        {
            int j = e[i];
            // cout << j << " " << dist[j] << " " << w[i] << " " << d << endl;
            if(dist[j] > d + w[i])
            {
                dist[j] = d + w[i];
                heap.push({dist[j], j});
            }
        }
    }
    
    if(dist[n] == 0x3f3f3f3f) return -1;
    return dist[n];
}

int main()
{
    memset(h, -1, sizeof h);
    cin >> n >> m;
    
    for(int i=0;i<m;i++)
    {
        int x, y, z;
        cin >> x >> y >> z;
        add(x, y, z);
    }
    int s = dijkstra();
    
    // for(int i=1;i<=n;i++) cout << dist[i] << " ";
    
    cout << s << endl;
    return 0;
}
复制代码

 

posted @   krystalZ2021  阅读(79)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示