洛谷 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;
}