[模板] dijkstra (堆优化)

复杂度O(mlogn)

输入起点s,可以得到从起点到各点的最短路距离数组dis[i]

过程:

1.初始化:清空标记数组,初始化距离数组设为inf,起点距离设为0,开优先队列,搜索起点

2.搜索:取出队首并pop,如果队首节点u的当前最短路比u的原先的最短路大则跳过,否则遍历u的邻接点如果v没有被访问过且u的最短路加上当前邻接边边权小于原先v的最短路,则更新v的最短路且搜索v

3.注意:优先队列重载时<和>是反的,所以在friend bool operator < (node a,node b){return a.d>b.d;}中是要a.d>b.d才能让优先队列中w小的优先,如果是a.d<b.d则是w大的优先

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
//typedef __int128_t LL;
typedef double db;
#define rep(a,b,c) for(ll a=b;a<=c;a++)
#define per(a,b,c) for(ll a=b;a>=c;a--)
#define go(a,b) for(ll a=head[b];a;a=e[a].to)
#define endl '\n'
#define V vector
#define pb push_back
#define mp make_pair
#define mem(a,b) memset(a,b,sizeof(a))
const ll amn=1e5+5,mod=1e9+7,inf=0x3f3f3f3f;
ll head[amn],etot;
struct eg{
    ll to,v;
    db w;
    eg(){}
    eg(ll to,ll v,db w):to(to),v(v),w(w){}
}e[amn];
void einit(){
    etot=0;
    mem(head,0);
}
void add(ll u,ll v,db w){
    e[++etot]=eg(head[u],v,w);
    head[u]=etot;
}
void adde(ll u,ll v,db w){
    e[++etot]=eg(head[u],v,w);
    head[u]=etot;
    e[++etot]=eg(head[v],u,w);
    head[v]=etot;
}
void sovle();
int main(){
    ios::sync_with_stdio(0);
    ll T=1;
    //cin>>T;
    while(T--){
        sovle();
    }
}
ll n,m,k;
ll s,t;

struct node{
    ll i,d;
    node(){}
    node(ll i,ll d):i(i),d(d){}
    friend bool operator < (node a,node b){
        return a.d>b.d;
    }
};
ll vis[amn];
ll dis[amn];
void dij(ll st){
    rep(i,0,m+1){
        vis[i]=0;
        dis[i]=inf;
    }
    dis[st]=0;

    priority_queue<node> q;
    while(q.size())q.pop();
    q.push(node(st,0));

    while(q.size()){
        node x=q.top();q.pop();
        ll u=x.i,d=x.d;
        if(vis[u])continue;
        vis[u]=1;
        go(i,u){
            ll v=e[i].v,w=e[i].w;
            if(!vis[v]&&d+w<dis[v]){
                dis[v]=d+w;
                q.push(node(v,dis[v]));
            }
        }
    }
}
void sovle(){

}

 

posted @ 2019-08-25 12:07  Railgun000  阅读(178)  评论(0编辑  收藏  举报