1. 程式人生 > 其它 >單源最短路徑

單源最短路徑

線段樹維護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;
}