题目背景
2018 年 7 月 19 日,某位同学在 NOI Day 1 T1 归程 一题里非常熟练地使用了一个广为人知的算法求最短路。
然后呢?
100→60100→60;
Ag→CuAg→Cu;
最终,他因此没能与理想的大学达成契约。
小 F 衷心祝愿大家不再重蹈覆辙。
题目描述
给定一个 �n 个点,�m 条有向边的带非负权图,请你计算从 �s 出发,到每个点的距离。
数据保证你能从 �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≤�≤1051≤n≤105;
1≤�≤2×1051≤m≤2×105;
�=1s=1;
1≤��,��≤�1≤ui,vi≤n;
0≤��≤1090≤wi≤109,
0≤∑��≤1090≤∑wi≤109。
本题数据可能会持续更新,但不会重测,望周知。
2018.09.04 数据更新 from @zzq
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int idx,g[N],e[2*N],ne[2*N],w[2*N],n,m,s,inf=0x3f3f3f3f;
bool st[N];
int dist[N];
typedef pair<int ,int> PII;
void add(int a,int b,int c){
e[idx]=b;
w[idx]=c;
ne[idx]=g[a];
g[a]=idx++;
}
void dijkstra(){
memset(dist,inf,sizeof dist);
priority_queue<PII,vector<PII>,greater<PII> > heap;
dist[s]=0;
heap.push({0,s});
while(!heap.empty()){
PII t=heap.top();
heap.pop();
int ver=t.second,distance=t.first;
if(st[ver])
continue;
st[ver]=true;
for(int i=g[ver];i!=-1;i=ne[i]){
int j=e[i];
if(dist[j]>distance+w[i])
dist[j]=distance+w[i];
heap.push({distance+w[i],j});
}
}
}
int main(){
cin>>n>>m>>s;
memset(g,-1,sizeof g);
for(int i=0;i<m;i++){
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
add(x,y,z);
}
dijkstra();
for(int i=1;i<n;i++){
cout<<dist[i]<<" ";
}
cout<<dist[n];
return 0;
}