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

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

洛谷传送门

题目背景

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

然后呢?

100 \rightarrow 60100→60;

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

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

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

题目描述

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

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

输入格式

第一行为三个正整数 n, m, sn,m,s。 第二行起 mm 行,每行三个非负整数 u_i, v_i, w_iu**i,v**i,w**i,表示从 u_iu**i 到 v_iv**i 有一条权值为 w_iw**i 的有向边。

输出格式

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


题解:

有向边。

代码:

#include<cstdio>
#include<queue>
#include<cstring>
#define int long long
using namespace std;
const int maxn=1e5+5;
const int maxm=2e5+5;
int n,m,s;
int tot,head[maxn],nxt[maxm<<1],to[maxm<<1],val[maxm<<1];
void add(int x,int y,int z)
{
	to[++tot]=y;
	nxt[tot]=head[x];
	head[x]=tot;
	val[tot]=z;
}
priority_queue<pair<int,int> >q;
int dist[maxn];
bool v[maxn];
void dijkstra()
{
	memset(dist,127,sizeof(dist));
	dist[s]=0;
	q.push(make_pair(0,s));
	while(!q.empty())
	{
		int x=q.top().second;
		q.pop();
		if(v[x])
			continue;
		v[x]=1;
		for(int i=head[x];i;i=nxt[i])
		{
			int y=to[i];
			if(dist[y]>dist[x]+val[i])
			{
				dist[y]=dist[x]+val[i];
				q.push(make_pair(-dist[y],y));
			}
		}
	}
}
signed main()
{
	scanf("%lld%lld%lld",&n,&m,&s);
	for(int i=1;i<=m;i++)
	{
		int x,y,z;
		scanf("%lld%lld%lld",&x,&y,&z);
		add(x,y,z);
	}
	dijkstra();
	for(int i=1;i<=n;i++)
		printf("%lld ",dist[i]);
	return 0;
}
posted @ 2020-12-03 15:59  Seaway-Fu  阅读(132)  评论(1编辑  收藏  举报