美文网首页
【算法篇-图论】dijkstra

【算法篇-图论】dijkstra

作者: 沧海无雨 | 来源:发表于2019-10-11 13:04 被阅读0次

一、适用条件

单源最短路问题、非负权图

二、算法思想

三、朴素的dijkstra(邻接矩阵存图)

时间复杂度分析

O(v*v), 顶点的二次方

题目来源:https://www.acwing.com/problem/content/851/

  1. Dijkstra求最短路 I

给定一个n个点m条边的有向图,图中可能存在重边和自环,所有边权均为正值。
请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出-1。
【输入格式】
第一行包含整数n和m。
接下来m行每行包含三个整数x,y,z,表示点x和点y之间存在一条有向边,边长为z。
【输出格式】
输出一个整数,表示1号点到n号点的最短距离。
如果路径不存在,则输出-1。
【数据范围】
1≤n≤500,
1≤m≤105,
图中涉及边长均不超过10000。
【输入样例】:
3 3
1 2 2
2 3 1
1 3 4
【输出样例】:
3

#include <bits/stdc++.h>
using namespace std;
const int maxn = 510;
const int INF = 0x3f3f3f;
int g[maxn][maxn], d[maxn];
bool vis[maxn];

void init(int n){
    for(int i=1; i<=n; i++)  // 初始化全部为不相连
        for(int j=1; j<=n; j++)
            g[i][j] = INF;
    for(int i=1; i<=n; i++){
        d[i] = INF;   // 最短距离初始化
        g[i][i] = 0;    // 防止有自环
        vis[i] = false;  // 标记点还未确定最短距离
    }
}

int main(){
    int n, m;
    scanf("%d %d", &n, &m);
    init(n);
    for(int i=1; i<=m; i++){
        int x, y, z;
        scanf("%d %d %d", &x, &y, &z);
        g[x][y] = min(g[x][y], z);  //重边的话,选较小的权值
    }
    d[1] = 0;     // 起点,此处是顶点1
    for(int i=1; i<=n; i++){
        int u, minx = INF;   // u是距离起点最近的点
        for(int j=1; j<=n; j++)
            if(!vis[j] && d[j]<minx){
                minx = d[j];
                u = j;
            }
        vis[u] = true;
        for(int j=1; j<=n; j++) // 松弛 
            d[j] = min(d[j], d[u]+g[u][j]);  // d[j]相当于g[1][j]
    }
    if(d[n]==INF)  // n是终点,判断是否连通
        printf("-1");
    else
        printf("%d", d[n]);
    return 0;
}

四、堆优化的dijkstra(邻接表存图)

题目来源:https://www.acwing.com/problem/content/852/

  1. Dijkstra求最短路 II

给定一个n个点m条边的有向图,图中可能存在重边和自环,所有边权均为正值。
请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出-1。
【输入格式】
第一行包含整数n和m。
接下来m行每行包含三个整数x,y,z,表示点x和点y之间存在一条有向边,边长为z。
【输出格式】
输出一个整数,表示1号点到n号点的最短距离。
如果路径不存在,则输出-1。
【数据范围】
1≤n,m≤105,
图中涉及边长均不超过10000。
【输入样例】:
3 3
1 2 2
2 3 1
1 3 4
【输出样例】:
3

与上一题,区别是n与m的区别,此处是稀疏图,上一题是稠密图。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 10010;
const int INF = 0x3f3f3f;
struct edge{
    int from, to, cost;
};
vector<edge> G[maxn];
typedef pair<int, int> P; // first是距离,second是顶点,pair排序默认是先first,再是second
int d[maxn], n;

void dijkstra(int s, int t){
    priority_queue<P, vector<P>, greater<P> > Q;  // 小根堆
    for(int i=1; i<=n; i++)
        d[i] = INF;
    d[s] = 0;
    Q.push(P(0, s));
    while(!Q.empty()){
        P u = Q.top();
        Q.pop();
        int v = u.second; // 顶点 
        if(d[v]<u.first)  // 已经处理过了 
            continue;
        for(int i=0; i<G[v].size(); i++){  //松弛
            edge e = G[v][i];
            if(d[e.to]>d[v]+e.cost) {
                d[e.to] = d[v]+e.cost;
                Q.push(P(d[e.to], e.to));  // 更新后的结点信息
            }
        }
    }
    cout << d[t];
}

int main(){
    int m, x, y, z;
    cin >> n >> m;
    for(int i=1; i<=m; i++){
        cin >> x >> y >> z;
        G[x].push_back((edge){x, y, z});
    }
    dijkstra(1, n); 
    return 0;
}

相关文章

  • 【算法篇-图论】dijkstra

    一、适用条件 单源最短路问题、非负权图 二、算法思想 三、朴素的dijkstra(邻接矩阵存图) 时间复杂度分析 ...

  • 图论:Dijkstra算法

    记9月23日学习Dijkstra算法用邻接矩阵存储稠密图,邻接表存储稀疏图,该算法适用单源最短路问题,朴素的Dij...

  • Dijkstra算法

    参考资料:1. 图论之Dijkstra最短路径算法2. Dijkstra算法时间复杂度 基本思路:维护一个从V0到...

  • 图论算法(四) Dijkstra算法

    代码 Dijkstra算法的思路:参见代码注释

  • 图论(1)-tarjan算法求强联通分量,割点,桥

    在LC里面的图论题,一般还是非常基础的,BFS,或者Dijkstra 为主。造成其实有很多经典的图论算法运用的不多...

  • 图论模板总结

    前言:图论那几个算法真的比较容易忘记,今天就来复习一下吧 0X00 模板总结 Dijkstra 算法本身就是用来求...

  • 图的最短路径

    Dijkstra算法&Floyd算法 一、Dijkstra算法 Dijkstra算法思想: 只计算v0出发到其他顶...

  • 深入解析Dijkstra's Algorithm ——

    什么是Dijkstra算法? Dijkstra算法是用来寻找最短路径最著名的算法之一。具体来说,Dijkstra算...

  • 图论之Dijkstra最短路径算法

    图论中最有名的问题可能就属最短路径了。最短路径问题要求解的是:如果从图中某一顶点(称为源点)到达另一顶点(称为终点...

  • 2021-06-04 从例题看Dijkstra算法

    /背景/在图论的学习中,非常有实用性的一个课题:最短路径。这里讨论一下Dijkstra算法求最短路径。**用于图中...

网友评论

      本文标题:【算法篇-图论】dijkstra

      本文链接:https://www.haomeiwen.com/subject/rhrsyctx.html