题目描述
给定一个 n n n 个点, m m m 条有向边的带非负权图,请你计算从 s s s 出发,到每个点的距离。
数据保证你能从 s s s 出发到任意点。
输入格式
第一行为三个正整数 n , m , s n, m, s n,m,s。 第二行起 m 行,每行三个非负整数 u i , v i , w i u_i, v_i, w_i ui,vi,wi ,表示从 u i u_i ui到 v i v_i vi有一条权值为 w i w_i wi的有向边。
输出格式
输出一行 n n n 个空格分隔的非负整数,表示 s s 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
#include<bits/stdc++.h>
using namespace std;
struct Dijkstra{
using PII = pair<int,int>;
int n;
vector<vector<PII>> G;
vector<int> dis;
vector<bool> vis;
void Init(int n){
this->n = n;
G.resize(n);
dis.resize(n);
vis.resize(n);
}
void add_Edge(int u, int v, int w){
G[u].push_back( {v,w} );
}
vector<int> get_Dist(int s){
for(int i = 0; i < n; i++) dis[i] = 2e9;
dis[s] = 0;
priority_queue<PII> pq;
pq.push( {0,s} );
while(pq.size()){
auto u = pq.top().second; pq.pop();
if(vis[u]) continue;
vis[u] = true;
for(auto t : G[u]){
int v = t.first, d = t.second;
if(dis[v] > dis[u] + d){
dis[v] = dis[u] + d;
pq.push( {-dis[v], v} );
}
}
}
return dis;
}
};
int main(){
int n,m,s;
cin >> n >> m >> s;
Dijkstra dij;
dij.Init(n + 1);
while(m--){
int u,v,w;
cin >> u >> v >> w;
dij.add_Edge(u,v,w);
}
auto ans = dij.get_Dist(s);
for(int i = 1; i < ans.size(); i++) cout << ans[i] << " ";
cout << endl;
return 0;
}