竞赛树优化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树+树的点分治

python机器学习入门模型优化(以决策树为例),来自kaggle竞赛

Prim算法