Dijkstra算法2

  1 // 再來一手精髓的Dijkstra
  2 // 複雜度O( E*log(V) )
  3 
  4 #include <cstdio>
  5 #include <iostream>
  6 #include <vector>
  7 #include <queue>
  8 
  9 using namespace std;
 10 
 11 const int max_N = 1000+2;
 12 const int max_E = 10000+2;
 13 const int INF = 1e9;
 14 
 15 int N,E;
 16 int d[max_N];
 17 
 18 // 來自何方,已經不重要了。
 19 // 其實是在鄰接表實現的過程當中,行號即爲來自的頂點
 20 struct edge
 21 {
 22     int to,cost;
 23 };
 24 // P.first表明距離,P.second表明頂點編號
 25 typedef pair<int,int> P;
 26 
 27 vector<edge> G[max_N];
 28 
 29 // 這一個算法下來,咱們在數組d中獲得了從s點到其他全部頂點的最短路程
 30 void dijkstra(int s)
 31 {
 32     // 創建最堆,來維護最小距離,能夠下降一層複雜度
 33     priority_queue< P,vector<P>,greater<P> > que;
 34 
 35     fill(d,d+N,INF);
 36     d[s]=0;
 37     que.push(P(0,s));
 38 
 39     while(!que.empty())
 40     {
 41         // 取出一個頂點,看是不是Dijstra算法中,已經肯定的最小頂點
 42         P p=que.top();
 43         que.pop();
 44 
 45         int v=p.second;
 46         // 讓咱們來看看這一步
 47         // 首先,每次取出堆中的最小元素
 48         // 而後去檢索這個堆頂元素的標號所對應的距離
 49         // 咦,你會發現堆頂這個距離,居然比取出的最小元素還要小
 50         // 驚訝?難道出錯了?沒有,考慮Dijkstra算法的流程,這個頂點確定是以前已經肯定過的最小頂點了,不須要考慮
 51         // 以前的實現是多加了一個flag數組來標記,這裏能夠省去這部份內存,直接用這個條件來判斷
 52         if(d[v]<p.first)
 53         {
 54             continue;
 55         }
 56 
 57         for(int i=0;i<G[v].size();++i)
 58         {
 59             edge e=G[v][i];
 60             if(d[e.to] > d[v] + e.cost)
 61             {
 62                 d[e.to]=d[v]+e.cost;
 63                 // 數組中維護這次被更新的節點便可,其他節點不須要維護
 64                 que.push(P(d[e.to],e.to));
 65             }
 66         }
 67     }
 68 
 69 }
 70 
 71 int main()
 72 {
 73     int a,b,c;
 74     scanf("%d %d",&N,&E);
 75     for(int i=0;i<E;++i)
 76     {
 77         scanf("%d %d %d",&a,&b,&c);
 78         edge e;
 79         e.to=b;
 80         e.cost=c;
 81         G[a].push_back(e);
 82         // 無向圖
 83         e.to=a;
 84         e.cost=c;
 85         G[b].push_back(e);
 86     }
 87 
 88     dijkstra(0);
 89 
 90     for(int i=0;i<N;++i)
 91     {
 92         printf("%d ",d[i]);
 93     }
 94 
 95     return 0;
 96 }
 97 
 98 /*
 99 7 10
100 0 1 2
101 0 2 5
102 1 2 4
103 1 3 6
104 1 4 10
105 2 3 2
106 3 5 1
107 4 5 3
108 4 6 5
109 5 6 9
110 
111 
112 */
相關文章
相關標籤/搜索