dirkstra最短路径模板 洛谷P4779

/*
    dirkstra最短路径模板   洛谷P4779
    最短路径之Dijkstra 迪杰斯特拉
    解决带权重的有向图,其权值只能是正值,不能解决负值问题。  无向图也可以,存两边就好了  nums[u].push_back()  nums[v].push_back() 
    基本思想:利用广度优先搜索的方法,更新起点到各个顶点的最短距离。
        是一种经典的求单源最短路径的一种方法。
    具体做法:定义一个数组T 保留源点到各顶点的最短距离,和一个数组表示以及遍历出最短路径的数组S
*/
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 2e5+10;
const int INF=1e18;

struct node{
    int v,w;
    bool operator <(const node &a)const{
        return a.w<w;   // 升序   与 sort 相同  a.w<b.w  // w本身就理解为b.w就好
	}
};

vector<node> nums[maxn]; // 邻接表     # 其他方式:邻接矩阵   链式前向星
priority_queue<node> q; // 优先队列  
int dis[maxn]; // 目的点到当前点的距离

void Dijkstra(int s){
    fill(dis,dis+maxn,INF);
	dis[s]=0; // 标记 出发点的距离为0
	q.push({s,0});  // 将出发点的信息存入优先队列
    while(!q.empty()){ // 判断优先队列是否为空
        node a = q.top(); // 取出当下距离最小的点(优先队列-升序排列 1 2 3 4  所有top=1)
        q.pop(); // 从队列中删除 取出的点
        int u = a.v;
        if(a.w!=dis[u]) continue;  // 如果取出点的距离和它对应dis中的值不同了,说明dis值以及有更好的路线了,因此跳过执行该点
        for(int i=0;i<nums[u].size();i++){ // 遍历与这个点相连的所有线路
            int v = nums[u][i].v; 
            if(dis[u]+nums[u][i].w<dis[v]){ // 如果这个点 加上本身 的距离 小于 当前到达目的地所需的距离
                dis[v]=nums[u][i].w+dis[u]; // 更新到达目的地的距离
                q.push({v,dis[v]}); // 将这个点存入队列
            }
        }
    }
}  // 思考:如果要记录最短的路径呢 该怎么记录呢?

void Solve(){
    int n,m,s;
    scanf("%lld %lld %lld",&n,&m,&s);
    int u,v,w;
    while(m--){
        scanf("%lld %lld %lld",&u,&v,&w);
        nums[u].push_back({v,w});
    }
    Dijkstra(s);
    for(int i=1;i<=n;i++)
        printf("%lld ",dis[i]);
}

signed main(){
    Solve();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值