單源最短路徑
阿新 • • 發佈:2022-04-22
線段樹維護dijkstra
#include<bits/stdc++.h> #define ls(x) x<<1 #define rs(x) (x<<1)+1 static char buf[100000],*pa=buf,*pb=buf; #define gc pa==pb&&(pb=(pa=buf)+fread(buf,1,100000,stdin),pa==pb)?EOF:*pa++ int read() { register int x(0); register char c(gc); while(c<'0'||c>'9')c=gc; while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=gc; return x; } long long int INF(1000000000000000000),start,ans[4000005],ans_pos[4000005],now[500005],T,minn[500005],sum[500005],b[500005],n,m,x,y,len; struct yuansu { long long int x,y,len; } bian[500005]; bool cmp(yuansu a,yuansu b) { return a.x<b.x; } using namespace std; void push_up(int id) { if(ans[ls(id)]<=ans[rs(id)]) { ans[id]=ans[ls(id)]; ans_pos[id]=ans_pos[ls(id)]; } else { ans[id]=ans[rs(id)]; ans_pos[id]=ans_pos[rs(id)]; } } void build(int l,int r,int id) { if(l==r) { if(l!=start)ans[id]=INF; else ans[id]=0; ans_pos[id]=l; return; } int mid((l+r)>>1); build(l,mid,ls(id)); build(mid+1,r,rs(id)); push_up(id); return; } void opc(int pos,int l,int r,int id,long long int zhi,int type) { //One Point Change if(l==r) { if(type)ans[id]=min(ans[id],zhi); else ans[id]=zhi; return; } int mid((l+r)>>1); if(pos<=mid)opc(pos,l,mid,ls(id),zhi,type); else opc(pos,mid+1,r,rs(id),zhi,type); push_up(id); return; } long long int query1() { return ans_pos[1]; } long long int query2() { return ans[1]; } int main() { n=read(),m=read(),start=read(); for(int i=1; i<=m; i++) { x=read(),y=read(),len=read(); bian[i].x=x; bian[i].y=y; bian[i].len=len; } sort(bian+1,bian+m+1,cmp); for(int i=1; i<=m; i++) { if(bian[i].x!=bian[i+1].x) sum[bian[i].x]=i; } for(int i=1; i<=n; i++)sum[i]=max(sum[i],sum[i-1]); build(1,n,1); T=n; while(T--) { int now=query1(),now_len=query2(); minn[now]=now_len; b[now]=1; opc(now,1,n,1,INF,0); for(int i=sum[now-1]+1; i<=sum[now]; i++) { if(!b[bian[i].y]) { opc(bian[i].y,1,n,1,now_len+bian[i].len,1); } } } for(int i=1; i<=n; i++) cout<<minn[i]<<" "; return 0; }