BZOJ 1726 洛谷 2865 [USACO06NOV]路障Roadblocks【次短路】
·求1到n的严格次短路。
【题解】
dijktra魔改?允许多次入队,改了次短路的值也要入队。
1 #include<cstdio> 2 #include<algorithm> 3 #define M 200010 4 #define N 5010 5 #define rg register 6 using namespace std; 7 int n,m,tot,last[N],dis[N],d2[N],pos[N]; 8 struct edge{ 9 int to,pre,dis; 10 }e[M]; 11 struct heap{ 12 int poi,dis; 13 }h[N]; 14 inline int read(){ 15 int k=0,f=1; char c=getchar(); 16 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 17 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 18 return k*f; 19 } 20 inline void add(int x,int y,int z){ 21 e[++tot]=(edge){y,last[x],z}; last[x]=tot; 22 } 23 inline void up(int x){ 24 int fa; 25 while((fa=x>>1)&&h[fa].dis>h[x].dis){ 26 swap(h[fa],h[x]); swap(pos[h[fa].poi],pos[h[x].poi]); 27 x=fa; 28 } 29 } 30 inline void down(int x){ 31 int son; 32 while((son=x<<1)<=tot&&h[son].dis<h[x].dis){ 33 if(h[son+1].dis<h[son].dis) son++; 34 if(h[son].dis<h[x].dis){ 35 swap(h[son],h[x]); swap(pos[h[son].poi],pos[h[x].poi]); 36 x=son; 37 } 38 else return; 39 } 40 } 41 inline void dijkstra(int x){ 42 h[pos[x]=tot=1]=(heap){x,dis[x]=0}; 43 while(tot){ 44 int now=h[1].poi; h[1]=h[tot--]; if(tot) down(1); 45 for(rg int i=last[now];i;i=e[i].pre){ 46 int tmp=dis[now]+e[i].dis,tmp2=d2[now]+e[i].dis,to=e[i].to; 47 bool flag=0; 48 if(dis[to]<tmp&&d2[to]>tmp) d2[to]=tmp,flag=1; 49 if(dis[to]<tmp2&&d2[to]>tmp2) d2[to]=tmp2,flag=1; 50 if(dis[to]>tmp) d2[to]=min(dis[to],tmp2),dis[to]=tmp,flag=1; 51 if(flag){ 52 if(!pos[to]) h[pos[to]=++tot]=(heap){to,dis[to]}; 53 else h[pos[to]].dis=dis[to]; 54 up(pos[to]); 55 } 56 pos[now]=0; 57 } 58 } 59 } 60 int main(){ 61 n=read(); m=read(); 62 for(rg int i=1;i<=n;i++) dis[i]=d2[i]=1e9; 63 for(rg int i=1;i<=m;i++){ 64 int u=read(),v=read(),w=read(); 65 add(u,v,w); add(v,u,w); 66 } 67 dijkstra(1); 68 printf("%d",d2[n]); 69 return 0; 70 }