【模板】单源最短路径(标准版)堆优化dijkstra

题目背景

2018 年 7 月 19 日,某位同学在 NOI Day 1 T1 归程 一题里非常熟练地使用了一个广为人知的算法求最短路。

然后呢?

100→60100→60;

Ag→CuAg→Cu;

最终,他因此没能与理想的大学达成契约。

小 F 衷心祝愿大家不再重蹈覆辙。

题目描述

给定一个 �n 个点,�m 条有向边的带非负权图,请你计算从 �s 出发,到每个点的距离。

数据保证你能从 �s 出发到任意点。

输入格式

第一行为三个正整数 �,�,�n,m,s。 第二行起 �m 行,每行三个非负整数 ��,��,��ui​,vi​,wi​,表示从 ��ui​ 到 ��vi​ 有一条权值为 ��wi​ 的有向边。

输出格式

输出一行 �n 个空格分隔的非负整数,表示 �s 到每个点的距离。

输入输出样例

输入 #1复制

4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4

输出 #1复制

0 2 4 3

说明/提示

样例解释请参考 数据随机的模板题

1≤�≤1051≤n≤105;

1≤�≤2×1051≤m≤2×105;

�=1s=1;

1≤��,��≤�1≤ui​,vi​≤n;

0≤��≤1090≤wi​≤109,

0≤∑��≤1090≤∑wi​≤109。

本题数据可能会持续更新,但不会重测,望周知。

2018.09.04 数据更新 from @zzq

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int idx,g[N],e[2*N],ne[2*N],w[2*N],n,m,s,inf=0x3f3f3f3f; 
bool st[N];
int dist[N];
typedef pair<int ,int> 	PII;
void add(int a,int b,int c){
	e[idx]=b;
	w[idx]=c;
	ne[idx]=g[a];
	g[a]=idx++;
}
void dijkstra(){
	memset(dist,inf,sizeof dist);
	priority_queue<PII,vector<PII>,greater<PII> > heap;
	dist[s]=0;
	heap.push({0,s});
	while(!heap.empty()){
		PII t=heap.top();
		heap.pop();
		int ver=t.second,distance=t.first;
		if(st[ver])
		continue;
		st[ver]=true;
		for(int i=g[ver];i!=-1;i=ne[i]){
			int j=e[i];
			if(dist[j]>distance+w[i])
			dist[j]=distance+w[i];
			heap.push({distance+w[i],j});
		}
	} 
}
int main(){
	cin>>n>>m>>s;
	memset(g,-1,sizeof g);
	for(int i=0;i<m;i++){
		int x,y,z;
		scanf("%d %d %d",&x,&y,&z);
		add(x,y,z); 
	}
	dijkstra();
	for(int i=1;i<n;i++){
		cout<<dist[i]<<" ";
	} 
	cout<<dist[n];
	return 0;
} 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

捉只树袋熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值