1. 程式人生 > >#dijkstra+zkw線段樹#洛谷 4779 洛谷 1339 【模板】單源最短路徑(標準版)熱浪

#dijkstra+zkw線段樹#洛谷 4779 洛谷 1339 【模板】單源最短路徑(標準版)熱浪

分析

首先為什麼要說這種方法呢,因為根據模板,zkw線段樹優化比STL堆快了一倍,所以說在此推薦我的熱浪題解


程式碼

#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int inf=1e9+7;
struct node{int y,w,next;}e[200005];
int n,m,s,bas=1,k=1,ls[100001],w[270001],p[270001],dis[100001];
inline
signed iut(){ rr int ans=0; rr char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) ans=(ans<<3)+(ans<<1)+c-48,c=getchar(); return ans; } inline void add(int x,int y,int w){ e[++k]=(node){y,w,ls[x]}; ls[x]=k; } inline void update(int x){ w[x]=(w[x<<
1]<w[x<<1|1])?w[x<<1]:w[x<<1|1]; p[x]=(w[x<<1]>w[x<<1|1])?p[x<<1|1]:p[x<<1]; } inline void print(int ans){ if (ans>9) print(ans/10); putchar(ans%10+48); } signed main(){ n=iut(); m=iut(); s=iut(); for (rr int i=1;i<=m;++i){ rr int
x=iut(),y=iut(),w=iut(); add(x,y,w); } while ((bas<<=1)<n+2); fill(w+1,w+2+(bas<<1),inf); fill(dis+1,dis+1+n,inf); fill(p+1,p+2+(bas<<1),inf); w[s+bas-1]=dis[s]=0; for (rr int i=0;i<n;++i) p[bas+i]=i+1; for (rr int i=bas-1;i;--i) update(i); while (w[1]<inf){ rr int x=p[1],y=p[1]+bas-1; w[y]=inf; for (y>>=1;y;y>>=1) update(y); for (rr int i=ls[x];i;i=e[i].next) if (dis[e[i].y]>dis[x]+e[i].w){ dis[e[i].y]=dis[x]+e[i].w; rr int t=e[i].y+bas-1; for (w[t]=dis[e[i].y],t>>=1;t;t>>=1) update(t); } } for (rr int i=1;i<=n;++i) print(dis[i]),putchar(i==n?10:32); return 0; }