来源:洛谷 P4779 【模板】单源最短路径(标准版)
题目
给定一个 n 个点,m 条有向边的带非负权图,请你计算从 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 ≤ n ≤ 105
1 ≤ m ≤ 2×105
s = 1
1 ≤ ui , vi ≤ n
0 ≤ wi ≤ 109
0 ≤ ∑ wi ≤ 109
题解
思路
标准的Dijkstra,不解释(然而第一次做时不会用优先队列,所以爆零了)
值得一提的是,朴素Dijkstra的时间复杂度好像是 O( n2 ) ,而优先队列优化的时间复杂度好像是 O( m log m ),在选择优不优化时看清数据范围(即 m = n2 时,比如某道最小生成树题,以后应该会发)。
代码是以前写的,所以码风和变量名不忍直视,甚至还出现了一些我自己都看不懂的蜜汁操作(
不过由于情怀问题还是发上来吧(其实是因为不想重新写一遍),以后有时间再重写。
代码
O( n2 ):
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cstring>
using namespace std;
int n,m,s,dis[10001],first[10001],next[500001];
bool vis[10001];
struct st
{
int s,f,jz;
}a[500001];
int main()
{
memset(dis,-1,sizeof(dis));
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a[i].s,&a[i].f,&a[i].jz);
if(first[a[i].s