• 竞赛树优化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
    ",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;
    }
  • 相关阅读:
    windows2019开发windows服务
    vue开发笔记
    kafka管理界面 kafka eagle
    WPF 无边框窗体改变大小和移动
    3种方法改变Linux的默认shell
    Linux,原来cd命令这样玩
    Linux中cp命令的使用方法
    Linux 中ls命令的使用
    如何查看Linux的内存使用率
    Linux中如何重命名文件
  • 原文地址:https://www.cnblogs.com/star-eternal/p/7643833.html
Copyright © 2020-2023  润新知