[模板] 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(){ }