代码如下:
#include<cstdio>
using namespace std;
bool vis[100001];
int wz[400004],tree[400004],inf=1000000002,dis[100001],n,m,s,first[100001],next[200002],u[200002],v[200002],w[200002];
int min(int x,int y){
if(x<y)return x;
return y;
}
void build(int k,int l,int r){
if(l==r){
tree[k]=dis[l];
wz[k]=l;
return;
}
int mid=(l+r)>>1;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
tree[k]=min(tree[k*2],tree[k*2+1]);
wz[k]=wz[k*2+1];
if(tree[k]==tree[k*2]){
wz[k]=wz[k*2];
}
}
void chan(int k,int l,int r,int x,int v){
if(x==l&&x==r){
tree[k]=v;
return;
}
int mid=(l+r)>>1;
if(x<l||x>r)return;
if(x<=mid)chan(k*2,l,mid,x,v);
if(x>mid)chan(k*2+1,mid+1,r,x,v);
tree[k]=min(tree[k*2],tree[k*2+1]);
wz[k]=wz[k*2+1];
if(tree[k]==tree[k*2]){
wz[k]=wz[k*2];
}
}
int main(){
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u[i],&v[i],&w[i]);
if(u[i]==s)dis[v[i]]=w[i];
next[i]=first[u[i]];
first[u[i]]=i;
}
for(int i=2;i<=n;i++)if(dis[i]==0)dis[i]=inf;
vis[1]=1;
build(1,1,n);
for(int i=1;i<=n-2;i++){
int d=wz[1];
vis[d]=1;//1->d->i
chan(1,1,n,d,inf);
for(int j=first[d];j!=0;j=next[j]){
if(dis[v[j]]>dis[d]+w[j]){
dis[v[j]]=dis[d]+w[j];
chan(1,1,n,v[j],dis[v[j]]);
}
}
}
for(int i=1;i<=n;i++)printf("%d ",dis[i]);
return 0;
}