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

折月煮酒 提交于 2019-12-04 00:22:40

如有乱码,请点击

 

题目背景

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

然后呢?

100 \rightarrow 6010060;

Ag \rightarrow CuAgCu;

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

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

题目描述

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

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

输入格式

第一行为三个正整数 N, M, SN,M,S。 第二行起 MM 行,每行三个非负整数 u_i, v_i, w_iui,vi,wi,表示从 u_iui 到 v_ivi 有一条权值为 w_iwi 的边。

输出格式

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

输入输出样例

输入 #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 \leq N \leq 1000001N100000;

1 \leq M \leq 2000001M200000;

S = 1S=1;

1 \leq u_i, v_i\leq N1ui,viN;

0 \leq w_i \leq 10 ^ 90wi109,

0 \leq \sum w_i \leq 10 ^ 90wi109。

 

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
int n,m,tot,s;
int head[100610],ver[1000610],edge[1000610],Next[1000610],d[100610];
bool v[100610];
priority_queue<pair<int, int> > q;
int read(){
	int a=0,b=1;
	char ch=getchar();
	while((ch<48||ch>57)&&ch!='-'){
		ch=getchar();
	}
	if(ch=='-'){
		b=-1;
		ch=getchar();
	}
	while(ch<48||ch>57){
		ch=getchar();
	}
	while(ch>47&&ch<58){
		a=a*10+ch-48;
		ch=getchar();
	}
	return a*b;
}
void add(int x,int y,int z){
	ver[++tot]=y;
	edge[tot]=z;
	Next[tot]=head[x];
	head[x]=tot;
}
void dijkstra(){
	memset(d,0x3f,sizeof(d));
	memset(v,0,sizeof(v));
	d[s]=0;
	q.push(make_pair(0,1));
	while(q.size()){
		int x=q.top().second;
		q.pop();
		if(v[x]){continue;}
		v[x]=1;
		for(int i=head[x];i;i=Next[i]){
			int y=ver[i],z=edge[i];
			if(d[y]>d[x]+z){
				d[y]=d[x]+z;
				q.push(make_pair(-d[y],y));
			}
		}
	}
}
int main() {
	n=read(),m=read(),s=read();
	for(int i=1;i<=m;i++){
		int x,y,z;
		x=read(),y=read(),z=read();
		add(x,y,z);
	}
	dijkstra();
	for(int i=1;i<=n;i++){
		printf("%d ",d[i]);
	}
	return 0;
}

  

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!