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 }
View Code
原文地址:https://www.cnblogs.com/DriverLao/p/8654198.html