洛谷 1359 租用游艇

【题解】

  裸的最短路。直接跑dijkstra即可。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #define LL long long
 5 #define rg register
 6 #define N 200010
 7 using namespace std;
 8 int n,tot,last[N],dis[N],pos[N];
 9 struct edge{
10     int to,pre,dis;
11 }e[N];
12 struct heap{
13     int poi,dis;
14 }h[N];
15 inline int read(){
16     int k=0,f=1; char c=getchar();
17     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
18     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
19     return k*f;
20 }
21 inline void up(int x){
22     int fa;
23     while((fa=(x>>1))&&h[fa].dis>h[x].dis) 
24         swap(h[fa],h[x]),swap(pos[h[fa].poi],pos[h[x].poi]),x=fa;
25 }
26 inline void down(int x){
27     int son;
28     while((son=(x<<1))<=tot){
29         if(h[son].dis>h[son+1].dis&&son<tot) son++;
30         if(h[son].dis<h[x].dis)
31             swap(h[son],h[x]),swap(pos[h[son].poi],pos[h[x].poi]),x=son;
32         else return;
33     }
34 }
35 inline void dijkstra(int x){
36     for(rg int i=1;i<=n;i++) dis[i]=1e9;
37     h[tot=pos[x]=1]=(heap){x,dis[x]=0};
38     while(tot){
39         int now=h[1].poi; h[1]=h[tot--]; if(tot) down(1);
40         for(rg int i=last[now],to;i;i=e[i].pre)
41         if(dis[to=e[i].to]>dis[now]+e[i].dis){
42             dis[to]=dis[now]+e[i].dis;
43             if(!pos[to]) h[pos[to]=++tot]=(heap){to,dis[to]};
44             else h[pos[to]].dis=dis[to];
45             up(pos[to]);
46         }
47         pos[now]=0;
48     }
49 }
50 int main(){
51     n=read();
52     for(rg int i=1;i<=n;i++)
53         for(rg int j=i+1;j<=n;j++) e[++tot]=(edge){j,last[i],read()},last[i]=tot;
54     dijkstra(1);
55     printf("%d
",dis[n]);
56     return 0; 
57 }
View Code
原文地址:https://www.cnblogs.com/DriverLao/p/9398059.html