1. 程式人生 > 實用技巧 >最短路——Dijkstra演算法

最短路——Dijkstra演算法

解決:單源最短路問題(一個源點到其餘所有點的最短路問題)

堆優化複雜度:O(nlogn)

演算法思想:可以理解為多米諾骨牌,先到達點t的骨牌有貢獻,後到達的骨牌無貢獻。利用貪心的思想

步驟:源點s

1:首先將所有的點分為兩類,一類是已經找到到源點s的最短路的點S,一類是沒有找到T。起初S中只有源點s

2:在s的所有直連鄰居中,找到最近的鄰居u,u肯定是骨牌最首先到達的,那麼記錄dis[u]的值,然後再在u的直連鄰居中+dis[u]的直連鄰居比較,找到最小的值v,記錄dis[v],下次再在v的直連鄰居中+dis[v]和s的直連鄰居以及u的直連鄰居+dis[u]中找最小值,如此查詢,直到找到所有的結點

const int N=1e5+10;
const int INF=1e9;
struct edge{
    int from,to,w;
    edge(int a,int b,int c){
        from=a,to=b,w=c;
    }
};
struct s_node{
    int id,n_dis;//id:結點號 n_dis:這個結點到起點的一個距離
    s_node(int b,int c) {
        id=b;
        n_dis=c;
    } 
    bool operator<(const struct s_node &a) const
{ return n_dis>a.n_dis; } }; int dis[N];//記錄所有結點到源點的最短距離 bool done[N];//true表示已經找到該結點的最短路 int pre[N]; vector<struct edge> E[N]; int n; void Print_path(int s,int t){ if(s==t) { cout<<s<<" "; return ; } Print_path(s,pre[t]); cout<<t<<"
"; } void dijkstra(int s){//s表示源點 for(int i=1;i<=n;i++) dis[i]=INF,done[i]=false; dis[s]=0; priority_queue<struct s_node>q; while(!q.empty()){ s_node u=q.top();q.pop(); if(done[u.id]) continue; done[u.id]=true; for(int i=0;i<E[u.id].size();i++){ struct edge y=E[u.id][i]; if(done[y.to]) continue; if(dis[y.to]>y.w+u.n_dis){ dis[y.to]=y.w+u.n_dis; q.push(s_node(y.to,dis[y.to])); pre[y.to]=u.id; } } } }