//采用堆优化 #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int Maxn=2e5+5; bool vis[Maxn<<1];//判断是否有经过 const int INF=0x7f7f7f7f; int n,m,s,dis[Maxn]; int head[Maxn<<1],top; struct Edge{int to,next,val,pre;}edge[Maxn<<1]; void addEdge(int u,int v,int val){ edge[++top].to=v; edge[top].next=head[u]; edge[top].pre; edge[top].val=val; head[u]=top; } struct Node{ int dis;//值 int pos;//当前点 Node(int dis, int pos):dis(dis),pos(pos){}//给堆里面加值 bool operator <(const Node &x) const{ return x.dis<dis;//定义堆为小根堆 } }; priority_queue<Node>q; void Dijkstra(int s){ memset(dis,INF,sizeof(dis)); //初始化为无穷大 dis[s]=0;//刚开始时为 0 q.push((Node){0,s});//存入当前点的值和点的位置 while(!q.empty()){//我们的目的就是直到队列为 空 ,否则就是还有路 Node temp=q.top();//将队头元素记录下来,因为这是值最小的 // printf("%d ",temp.pos); //优化了步骤 2 q.pop(); int u=temp.pos;//当前的点的位置 int d=temp.dis;//当前的点距离源点的最短路径 if(vis[u]) continue;//遍历过的话就不用再次遍历 vis[u]=true; for(int i=head[u];i;i=edge[i].next){ int v=edge[i].to; if(dis[v]>dis[u]+edge[i].val){//更新 dis[v]=dis[u]+edge[i].val; if(!vis[v]) q.push((Node){dis[v],v}); } } } } int main(){ scanf("%d%d%d",&n,&m,&s); for(int i=1;i<=m;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); addEdge(u,v,w);//有向边 } Dijkstra(s); for(int i=1;i<=n;i++) printf("%d ",dis[i]); return 0; }