Dijkstra:从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。适用于单源最短路径问题
//堆优化dijsktra
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;//距离 下标
const int N=2e5+10;
const int inf=0x3fffffff;
int n, m, s;
int dis[N],vis[N];
vector<pii> g[N];
priority_queue<pii, vector<pii>, greater<pii> > q;//按照pair的第一维排序
void dijk(){
q.push({0, s});
dis[s] = 0;
while(!q.empty()){//只能用于所有边权为正数的图
int now = q.top().second;//top一定是dis最小的点,从堆里第一个出来的是最短路
q.pop();
if(vis[now]){ //有可能堆里会出现同一个now
continue;
}
vis[now] = 1;//一旦确定了某点的最短路距离,那么该点被标记为1
for(int i=0;i<g[now].size();i++)
{
int v = g[now][i].second, w = g[now][i].first;
if(dis[now] + w < dis[v]){
dis[v] = dis[now] + w;
q.push({dis[v], v});
}
}
}
return;
}
int main(){
cin >> n >> m >> s;
int u, v, w;
for(int i = 0; i < m; i++){
cin >> u >> v >> w;
g[u].push_back({w, v});//{边权,点}
}
for(int i=0;i<=n;i++)
dis[i]=inf;
dijk();
for(int i = 1; i <= n; i++)
printf("%d%c", dis[i], (i == n) ?'\n': ' ');
return 0;
}