P4779 【模板】单源最短路径(标准版)

原题链接

题解

Dijkstra算法+反向索引堆优化

code

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
const int M=1e5+5;
const ll MAX=1e14+5;
ll head[M],Next[N],to[N],w[N],vis[M],dis[M];
int n,m,s,CNT=1;
struct Node{
    int way;
    ll value;
};
Node heap[N];
int len=0;
void Swap(int i,int j){
    Node tem=heap[i];
    heap[i]=heap[j];
    heap[j]=tem;
    vis[heap[i].way]=i;
    vis[heap[j].way]=j;
}
void initial(){
    for (int i=1;i<=n;i++) {
        vis[i]=-1;
        dis[i]=MAX;
    }
}
void build(){
    int from,TO,weight;
    cin>>from>>TO>>weight;
    Next[CNT]=head[from];
    head[from]=CNT;
    to[CNT]=TO;
    w[CNT]=weight;
    CNT++;
}
void heapinsert(int i){
    int l=(i-1)/2;
    while (i>0){
        if (heap[i].value<heap[l].value)
            Swap(i,l);
        else break;
        i=l;
        l=(i-1)/2;
    }
}
void heapfy(int i){
    int l=i*2+1;
    while (l<len){
        int best=l+1<len && heap[l+1].value<heap[l].value ? l+1 : l;
        best=heap[best].value<heap[i].value ? best : i;
        if (best==i) break;
        Swap(best,i);
        i=best;
        l=i*2+1;
    }
}
void addupdateignor(int id,ll weight){
    Node x;
    x.way=id;
    x.value=weight;
    if (vis[id]==-1){
        vis[id]=len;
        dis[id]=weight;
        heap[len++]=x;
        heapinsert(vis[id]);
    }
    else if (vis[id]>=0){
        if (weight<dis[id]){
            dis[id]=weight;
            heap[vis[id]].value=weight;
            heapinsert(vis[id]);
        }
    }
}
int main(){
    cin>>n>>m>>s;
    initial();
    for (int i=1;i<=m;i++) build();
    addupdateignor(s,0);
    while (len!=0){
        Node x=heap[0];
        vis[x.way]=-2;
        heap[0]=heap[--len];
        heapfy(0);
        for (int i=head[x.way];i>0;i=Next[i])
            addupdateignor(to[i],x.value+w[i]);
    }
    for (int i=1;i<=n;i++){
        if (i==1) cout<<dis[i];
        else cout<<" "<<dis[i];
    }
    return 0;
}

 

posted @ 2024-03-29 23:58  黑屿白  阅读(77)  评论(0)    收藏  举报