#include<iostream>
#include<vector>
#include<queue>
using namespace std;
int n,m,s;
struct Hi {
//到达的点、边权重
int to,w;
};
const int maxn = 1e8;
int dis[160000]; //存放所求顶点s到其他顶点的最短边
int vis[160000]; //记录是否遍历过
/*
v存放的数据类型是结构体 Hi
若v[1].push_back( (Hi){2,3} ) 表示顶点1到顶点2有一边权重为3的边,即把 (Hi){2,3} 压进v[1]
此时顶点1有1条出边 :1->2
若v[1].push_back( (Hi){3,4} ) 表示顶点1到顶点3有一边权重为4的边,即把 (Hi){3,4} 压进v[1]
此时顶点1有2条出边:1->2和1->3
*/
//邻接表
vector<Hi>v[160000];
/*
q放的数据类型是 pair<dis[点],点>
make_pair<3,2> :所求顶点s到顶点2的最短边为3 (dis[2])
此优先队列按pair中的第一个值排序,即按dis[]排序,即队头存放着最短边
*/
priority_queue< pair<int,int> , vector< pair<int,int> > , greater<pair<int,int>> >q;
void dijkstra() {
//初始化dis数组
for(int i = 1; i <= n; i++) {
dis[i] = maxn;
}
dis[s] = 0; //自己到自己的最短边为0
/*
第一轮更新 dis[]
如果前面执行过 v[s].push_back( (Hi){y,z} ); 那么说明顶点s有出边
因为是求顶点s到其他顶点的最短边,所以这里初始化就直接从 v[s]里面拿
*/
for(auto i:v[s]) {
dis[i.to] = i.w;
}
//点s到点s的距离为0
q.push(make_pair(0,s));
while(!q.empty()) {
int t = q.top().second; //拿出队头pair中的 second值
q.pop();
if(vis[t] == 1) continue;
vis[t] = 1;
for(auto i: v[t]) {
if(dis[i.to] >= dis[t] + i.w) {
dis[i.to] = dis[t] + i.w;
q.push( {dis[i.to],i.to} );
}
}
}
}
int main() {
cin >> n >> m >> s;
while(m--) {
int x,y,z;
cin >> x >> y >> z;
v[x].push_back( (Hi) {
y,z
} );
}
dijkstra();
for(int i=1; i<=n; i++) {
if(dis[i] == maxn) {
cout << -1 << endl;
} else {
cout << dis[i];
}
if(i!=n) {
cout<<" ";
}
}
}
dijkstra堆优化
最新推荐文章于 2024-02-05 20:16:36 发布