版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sugar_free_mint/article/details/84589379
分析
首先为什么要说这种方法呢,因为根据模板,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;
}