每日一题 第二期 洛谷 最短路径

【模板】单源最短路径(标准版)

题目链接

题目背景

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

然后呢?

100 → 60 100 \rightarrow 60 100→60;

Ag → Cu \text{Ag} \rightarrow \text{Cu} Ag→Cu;

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

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

题目描述

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

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

输入格式

第一行为三个正整数 n , m , s n, m, s n,m,s。

第二行起 m m m 行,每行三个非负整数 u i , v i , w i u_i, v_i, w_i ui,vi,wi,表示从 u i u_i ui 到 v i v_i vi 有一条权值为 w i w_i wi 的有向边。

输出格式

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

样例 #1

样例输入 #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 ≤ n ≤ 1 0 5 1 \leq n \leq 10^5 1≤n≤105;

1 ≤ m ≤ 2 × 1 0 5 1 \leq m \leq 2\times 10^5 1≤m≤2×105;

s = 1 s = 1 s=1;

1 ≤ u i , v i ≤ n 1 \leq u_i, v_i\leq n 1≤ui,vi≤n;

0 ≤ w i ≤ 1 0 9 0 \leq w_i \leq 10 ^ 9 0≤wi≤109,

0 ≤ ∑ w i ≤ 1 0 9 0 \leq \sum w_i \leq 10 ^ 9 0≤∑wi≤109。

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

2018.09.04 数据更新 from @zzq

思路:本题考察最短路,与本人之前写过的文章相符

链接最短路问题

堆优化版的Dijkstra

AC代码:

cpp 复制代码
#include<map>
#include<set>
#include<stack>
#include<cmath>
#include<queue>
#include<string>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<numeric>
#define endl '\n'
using namespace std;

typedef long long ll;
typedef pair<int, int>PII;
const int N=3e5+10;
const int MOD=998244353;
const int INF=0X3F3F3F3F;
const int dx[]={-1,1,0,0,-1,-1,+1,+1};
const int dy[]={0,0,-1,1,-1,+1,-1,+1};
const int M = 1e4 + 10;

int n, m, s;
int h[N], idx, e[N], ne[N], w[N];
int dis[N];
int st[N];

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

void dist()
{
	memset(dis, 0x3f, sizeof dis);
	dis[s] = 0;
	priority_queue<PII, vector<PII>, greater<PII>>heap;
	heap.push({0, s});
	while(heap.size()){
		auto t = heap.top();
		heap.pop();
		int ver = t.second ;
		if(st[ver]) continue;
		st[ver] = 1;
		for(int i = h[ver]; i != -1; i = ne[i])
		{
			int j = e[i];
			if(dis[j] > w[i] + dis[ver] && !st[j])
			{
				dis[j] = w[i] + dis[ver];
				heap.push({dis[j], j});
			}
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	memset(h, - 1, sizeof h);
	cin >> n >> m >> s;
	for(int i = 1; i <= m; i ++)
	{
		int a, b, c;

		
		cin >> a >> b >> c;
		add(a, b, c);
	}
	dist();
	for(int i = 1; i <= n; i ++)
	{
		cout << dis[i] << " ";
	}
	cout << endl;
	return 0;
}
相关推荐
抓饼先生8 分钟前
C++ 20 视图view笔记
linux·开发语言·c++·笔记·c++20
大可门耳14 分钟前
qt调用cef的Demo,实现js与C++之间的交互细节
javascript·c++·经验分享·qt
半桔19 分钟前
【STL源码剖析】二叉世界的平衡:从BST 到 AVL-tree 和 RB-tree 的插入逻辑
java·数据结构·c++·算法·set·map
R_.L40 分钟前
【项目】 :C++ - 仿mudou库one thread one loop式并发服务器实现(代码实现)
服务器·开发语言·c++
R_.L41 分钟前
【项目】 :C++ - 仿mudou库one thread one loop式并发服务器实现(模块划分)
服务器·c++
塔中妖1 小时前
【华为OD】分割数组的最大差值
数据结构·算法·华为od
weixin_307779131 小时前
最小曲面问题的欧拉-拉格朗日方程 / 曲面极值问题的变分法推导
算法
RTC老炮2 小时前
webrtc弱网-AlrDetector类源码分析与算法原理
服务器·网络·算法·php·webrtc
孤廖2 小时前
【算法磨剑:用 C++ 思考的艺术・Dijkstra 实战】弱化版 vs 标准版模板,洛谷 P3371/P4779 双题精讲
java·开发语言·c++·程序人生·算法·贪心算法·启发式算法
躯坏神辉2 小时前
c++怎么读取文件里的内容和往文件里写入数据
c++