竞赛树优化Dijkstra(可改堆)
Posted star_eternal
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了竞赛树优化Dijkstra(可改堆)相关的知识,希望对你有一定的参考价值。
竞赛树优化Dijkstra效率非常高,如果不懂竞赛树,请看这里
附上代码
#include<cstdio> #define N (100000+10)*2 #define M 200000+10 using namespace std; int head[N],ednum=1,dis[N],book[N]; struct Edge{int next,to,d;}edge[M]; void add(int from,int to,int d){edge[++ednum]=(Edge){head[from],to,d};head[from]=ednum;} int n,m; struct heap{int val,who;}h[N]; heap min(heap a,heap b) { return (a.val<b.val)?a:b; } void update(int i) { if(i==1)return; h[i/2]=min(h[i],h[i^1]);update(i/2); return; } void Dijkstra() { for(int i=1;i<=2*n-1;i++){ dis[i]=h[i].val=1e9; h[i].who=i; } h[n].val=0; update(n); while(h[1].val!=1e9)//竞赛树非空 { int val=h[1].val; int who=h[1].who; int u=who-(n-1); dis[u]=val; //printf("%d %d\n",u,dis[u]); h[who].val=1e9; update(who);//删除并调整 for(int i=head[u];i;i=edge[i].next) { int v=edge[i].to; if(dis[v]>dis[u]+edge[i].d) { dis[v]=dis[u]+edge[i].d; h[v+(n-1)].val=dis[u]+edge[i].d; update(v+(n-1));//修改并调整 } } } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ int u,v,d;scanf("%d%d%d",&u,&v,&d); add(u,v,d); } Dijkstra(); if(dis[n]==1e9){printf("-1");return 0;} printf("%d",dis[n]); return 0; }
以上是关于竞赛树优化Dijkstra(可改堆)的主要内容,如果未能解决你的问题,请参考以下文章
bzoj3073[Pa2011]Journeys 线段树优化建图+堆优化Dijkstra
BZOJ3073[Pa2011]Journeys 线段树+堆优化Dijkstra
[CF787D]遗产(Legacy)-线段树-优化Dijkstra(内含数据生成器)
bzoj4016[FJOI2014]最短路径树问题 堆优化Dijkstra+DFS树+树的点分治