思路我写注释里了,感觉思路也没问题啊
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
#define endl '\n'
typedef int INT;
//#define int long long
inline int read(){
int x=0,y=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
return x*y;
}
inline void write_base(int x){
if(x>9)write_base(x/10);
putchar('0'+x%10);
}
inline void write(int x){
if(x<0)putchar('-'),x*=-1;
write_base(x);
putchar(' ');
}
using namespace __gnu_pbds;
/********************************************************/
typedef pair<int,int> pii;
const int N=1e5+1;
cc_hash_table<int,cc_hash_table<int,int>>h; //哈希表存距离
vector<int>son[N];int vis[N]; //son[i][j]表示边i,j。我将vis[s]设为1,所以用vis来同时存储距离和是否被确定。最后输出vis[i]-1;
INT main(){//ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n=read(),m=read(),s=read();
while(m--){
int u=read(),v=read(),w=read();
if(u==v)continue; //去除自环
if(h[u][v]){ //如果存在u到v的距离(边),选择最小距离作为距离,否则做边u,v并存储h[u][v];
if(h[u][v]>w)
h[u][v]=w;
}else
h[u][v]=w,
son[u].push_back(v);
}
priority_queue<pii,vector<pii>,greater<pii>>q;
q.push(pii{1,s});
while(q.size()){
int dis=q.top().first,now=q.top().second;
q.pop();
if(vis[now])continue; //如果节点距离已经确定,则continue;
vis[now]=dis;
for(int i:son[now]) //遍历以now为起点的边,如果距离没有被确定则将距离和节点编号入堆;
if(vis[i]==0)
q.push(pii{vis[now]+h[now][i],i});
}
for(int i=1;i<=n;++i) //输出vis[i]-1;
write(vis[i]-1);
}