#include<bits/stdc++.h>
#include<queue>//很重要
using namespace std;
vector<int>g[100005];//记录一个点和那些边相连
vector<int>l[100005];//记录一个点和别的边的长度
int d[100005];//起点到每一点的距离
bool done[100005];//标记是否走过
const int inf=2147483647;
struct Edge
{
int i;
int v;
bool operator < (const Edge& rsh)const//[看不懂来这里](https://www.cnblogs.com/Deribs4/p/5657746.html)
{
return rsh.v<v;
}
};
priority_queue<Edge>q;//必须用优先队列
int main()
{
int n,m,s;
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
g[x].push_back(y);//压入相连点
l[x].push_back(z);//压入距离
}
for(int i=1;i<=n;i++)
{
d[i]=inf;//记为无穷大
}
d[s]=0;//起点至0
Edge h;
h.i=s;
h.v=0;
q.push(h);//压入起点的编号和数值
while(!q.empty())//若队列不为空
{
Edge x;
x=q.top();//取出首端节点(第一优化,无需便利其它点)
q.pop();
if(done[x.i])
{
continue;
}
done[x.i]=true;
for(int j=0;j<g[x.i].size();j++)//直接便利长度(优化2,无需便利其它点)
{
if(d[g[x.i][j]]>d[x.i]+l[x.i][j])//如果情况更优
{
d[g[x.i][j]]=d[x.i]+l[x.i][j];
Edge k;
k.i=g[x.i][j];
k.v=d[g[x.i][j]];
q.push(k);//重新压入
}
}
}
for(int i=1;i<=n;i++)
{
printf("%d ",d[i]);
}
return 0;
}
ps:很多人会认为需更改队列数值(我不会),拜托,这是优先队列
ps:queue头文件可以让你在打出一个队列s.时,会弹出很多函数(队列用的)