竞赛树优化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;
}

 

posted @ 2017-10-10 07:40  star_eternal  阅读(783)  评论(0编辑  收藏  举报