![](https://img-blog.csdnimg.cn/img_convert/69b308f6f3cb2e45aad807aef2c9fa77.png)
![](https://img-blog.csdnimg.cn/img_convert/6b270a9e4cd80ef7a1aa8bc38e6cdc45.png)
include<iostream>
#include<cstring>
#include<queue>
using namespace std;
typedef pair<int ,int>PII;
const int N=1e5+10,M=2*N;
int n,m,s;
bool vis[N];//
int dis[N];
//邻接表(一个结构体(to:目的地:w:权重;next:head[u]用于连接于起点有关的路线),一个数组,一个下标指针)
struct E
{
int to,w,next;
}doge[M];
int head[N],cnt;
void adddoge(int u,int v,int w)//加入边,邻接表
{
doge[++cnt].to=v;//前置++
doge[cnt].w=w;
doge[cnt].next=head[u];
head[u]=cnt;
}
void dijkstra()//dijkstra
{
memset(dis,0x3f,sizeof dis);//***
dis[s]=0;//***
priority_queue<PII,vector<PII>,greater<PII>>q;//***注意是大顶堆
q.push({0,s});//**先再循环外把起点压入队列(两个参数,1:dis[i](起点的当前点的距离),2:当前点的序号)
while(q.size())//**循环
{
int t=q.top().second;//拿出堆顶元素的(具体为当前点的序号)
q.pop();//拿完弹出
if(vis[t])continue;//该点已经访问过,就不用再访问
//如果进行到下面就代表t点还没访问
vis[t]=1;//标记访问过
for(int i=head[t];i!=0;i=doge[i].next)//遍历
{
int j=doge[i].to;//***方便下面引用
if(dis[j]>dis[t]+doge[i].w)//如果小
{
dis[j]=dis[t]+doge[i].w;//更新
q.push({dis[j],j});//更新过的压入队列
}
}
}
}
int main()
{
cin>>n>>m>>s;
for(int i=1;i<=m;i++)
{
int u,v,w;
cin>>u>>v>>w;
adddoge(u,v,w);
}
dijkstra();
for(int i=1;i<=n;i++)
{
cout<<dis[i]<<" ";
}
return 0;
}
okk