用線段樹寫Dijkstar
阿新 • • 發佈:2017-11-18
truct ++i 感覺 mark noip cst 好玩 sta ==
如題
noip前就想用線段樹優化Dijkstar
寫那啥,感覺挺好玩的
反正現在退役了也是閑的,寫了個線段樹優化的Dijkstar
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn =10007; const int maxm = 500007; const int INF = 0x7fffffff; int n,m; inline int read() { int x=0; char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); return x; } struct node{ int v,next,w; }edge[maxm]; int num=0,head[maxn]; inline void add_edge(int a,int b,int c) { edge[++num].v=b;edge[num].w=c;edge[num].next=head[a];head[a]=num; } int dis[maxn],ans[maxn],s,t; int tree[maxn<<2],leaf; inline int check(int i,int j) { return dis[i]<dis[j]?i:j; } inline void build() { std::memset(dis,0x3f,sizeof dis);// for(int i=0;i<=n+1;i++) dis[i]=INF; for(leaf=1;leaf<=n;leaf<<=1);--leaf; for(int i=1;i<=n;++i)tree[leaf+i]=i; } inline void modify(int x,int y) { dis[x]=y,x+=leaf,x>>=1; while(x) tree[x]=check(tree[x<<1],tree[x<<1|1]),x=x>>1; } void dijkstra(int s) { build(); dis[s]=0; int u=s; for(int i=1;i<=n;++i) { ans[u]=dis[u]; const int disu=dis[u]; modify(u,INF); for(int j=head[u];j;j=edge[j].next){ int v=edge[j].v; if(dis[v]<INF&&dis[v]>disu+edge[j].w) modify(v,disu+edge[j].w); } u=tree[1]; } } inline void put(int x) { if (x > 9) put(x / 10); putchar(x % 10 + 48); } int main() { int k; n=read(),m=read(),k=read(); for(int a,b,c,i=1;i<=m;++i) { a=read(),b=read(),c=read(); add_edge(a,b,c); } dijkstra(k); for(int i=1;i<=n;++i) { if(dis[i]==0x3f3f3f3f)ans[i]=INF; put(ans[i]), putchar(' '); } return 0; }
用線段樹寫Dijkstar