优先队列(堆优化)的dijkstra算法

Posted guaguastandup

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了优先队列(堆优化)的dijkstra算法相关的知识,希望对你有一定的参考价值。

这个应该已经是终极版本了......................

再优化我也优化不来了

调了一个多小时

崩溃啊

邻接矩阵不好吗

优化个什么劲啊TUT

 

好累的

TUT

 
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int inf = 0x3f3f3f3f;
const int maxn = 1e6+100;
int head[2000010],dis[200010],tot,n,m,a;
bool vis[maxn]={false};
struct edge{
    int v,w,next;
}e[maxn];
struct node{    
    int pos;    
    int dis;
    bool operator <( const node &x )const{
        return x.dis < dis;
    }
};    
int read(){
    int x=0,f=1;char c=getchar();
    while(c<0||c>9){if(c==-) f=-1;c=getchar();}
    while(c>=0&&c<=9) x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*f;
}
void add(int u,int v,int w){
    tot++;
    e[tot].v=v;
    e[tot].w=w;
    e[tot].next=head[u];
    head[u]=tot;
}
void init(){
    n=read(),m=read(),a = read();
    for(int i=1,u,v,w;i<=m;++i){
        u=read(),v=read(),w=read();
        add(u,v,w);
    }
}
void dijkstra(int x){
    priority_queue<node>q;   
    memset(dis, inf, sizeof(dis));
    dis[x] = 0;
    q.push((node){x,0});
    while(!q.empty()){
        node t = q.top();
        q.pop();
        int u = t.pos;
        if(vis[u])continue;
        vis[u] = true;//u是目前到达的最短处,从这个点向外松弛
        for (int i = head[u]; i;i=e[i].next){//枚举这个点的所有邻边
            int now = e[i].v;
            if((dis[now]>dis[u]+e[i].w)&&!vis[now]){
                dis[now] = dis[u] + e[i].w;
                q.push((node){now, dis[now]});//入队
            }
        }
    }
    return;
}
int32_t main(){
    init();
    dijkstra(a);
    for (int i = 1; i <= n-1;i++){
        if(dis[i]>=inf)
            printf("2147483647 ");
        else
            printf("%lld ", dis[i]);
    }
     if(dis[n]>=inf)
            printf("2147483647");
        else
            printf("%lld", dis[n]);
    system("pause");
    return 0;
}

 我又用pair存了一遍,不知道为什么,跑得比结构体node慢

TUT还加了常数优化和快读都不行

900多ms 卡得很紧 不知道为什么

待解决!

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define re register
#define il inline
typedef pair<int, int> p;
const int inf = 0x3f3f3f3f;
const int maxn = 1e6+100;
int head[2000010],dis[200010],tot,n,m,a;
bool vis[maxn]={false};
struct edge{
    int v,w,next;
}e[maxn];  
il int read(){
    re int x=0,f=1;char c=getchar();
    while(c<0||c>9){if(c==-) f=-1;c=getchar();}
    while(c>=0&&c<=9) x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*f;
}
il void add(int u,int v,int w){
    tot++;
    e[tot].v=v;
    e[tot].w=w;
    e[tot].next=head[u];
    head[u]=tot;
}
il void init(){
    n=read(),m=read(),a = read();
    for(re int i=1,u,v,w;i<=m;++i){
        u=read(),v=read(),w=read();
        add(u,v,w);
    }
}
il void dijkstra(int x){
    priority_queue<p, vector<p>, greater<p> > q;
    memset(dis, inf, sizeof(dis));
    dis[x] = 0;
    q.push(p(0, x));
    while(!q.empty()){
        p t = q.top();
        q.pop();
        re int u=t.second;
        if(vis[u])continue;
        vis[u] = true;//u是目前到达的最短处,从这个点向外松弛
        for (re int i = head[u]; i;i=e[i].next){//枚举这个点的所有邻边
            re int now = e[i].v;
            if((dis[now]>dis[u]+e[i].w)&&!vis[now]){
                dis[now] = dis[u] + e[i].w;
                q.push(p(dis[now],now));//入队
            }
        }
    }
    return;
}
int32_t main(){
    init();
    dijkstra(a);
    for (re int i = 1; i <= n-1;i++){
        if(dis[i]>=inf)
            printf("2147483647 ");
        else
            printf("%lld ", dis[i]);
    }
     if(dis[n]>=inf)
            printf("2147483647");
        else
            printf("%lld", dis[n]);
    system("pause");
    return 0;
}

 

以上是关于优先队列(堆优化)的dijkstra算法的主要内容,如果未能解决你的问题,请参考以下文章

最短路Dijkstra+ 链式前向星+ 堆优化(优先队列)

Dijkstra+优先队列 堆优化

最短路径-dijkstra算法

配对堆优化Dijkstra算法小记

dijkstra模板(好像是斐波那契额堆优化,但我为什么看起来像优先队列优化,和spfa一样)

优先级队列(小顶堆)的dijkstra算法