Advertisement
Guest User

Explicatie: algoritmul lui Dijkstra

a guest
Jan 30th, 2016
397
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.21 KB | None | 0 0
  1. /// priority_queue se afla in libraria <queue>
  2.  
  3. #include <fstream>
  4. #include <queue>
  5. #include <vector>
  6.  
  7. using namespace std;
  8.  
  9. ifstream in("dijkstra.in");
  10. ofstream out("dijkstra.out");
  11.  
  12. const int MAX_N = 100000; /// Valoarea maxima pentru N.
  13. const int INF = 0x7fffffff; /// Un truc, valoarea e scrisa in baza 16. Reprezinta cel mai mare numar care poate fi tinut pe int.
  14.  
  15. class Node { /// Clasa de care se va folosi priority_queue.
  16. public: /// Daca nu faci astea publice, nu merge.
  17.     int index; /// Indicele nodului.
  18.     int dist; /// Distanta pana la nod pe care o tin in heap.
  19.  
  20.     bool operator <(const Node &other) const { /// Operatorul < pe care priority_queue il foloseste daca il gaseste in clasa.
  21.         return this->dist > other.dist; /// Semnul e invers. Heapul sorteaza dupa astea, dar tine si indicele. Ca si cum ai sorta un struct.
  22.     }
  23. };
  24.  
  25. struct Edge { /// Edge : se tine minte pentru lista de adiacenta.
  26.     int other; /// Vecinul nodului.
  27.     int cost; /// Costul mucheiei.
  28. };
  29.  
  30. int n, m; /// n, m din enuntul problemei.
  31. int D[1 + MAX_N]; /// Distantele pana la noduri.
  32. vector < Edge > adjList[1 + MAX_N]; /// Lista de adiacenta.
  33. priority_queue < Node > Q; /// priority_queue, declarat simplu pe clasa Node, fiindca are operator de < incorporat.
  34.  
  35. void dijkstra(int s) {
  36.     int u, d, v, c, i;
  37.  
  38.     for(i = 1; i <= n; i++) D[i] = INF; /// Setez distantele pe INF.
  39.     D[s] = 0; /// Distanta pana la sursa este 0.
  40.     Q.push(Node{s, 0}); /// Adaug in heap sursa.
  41.  
  42.     while(Q.empty() == false) { /// Cat timp inca mai am noduri in heap.
  43.         u = Q.top().index; /// u este indicele nodului
  44.         d = Q.top().dist; /// d este distanta pana la nodul cu distanta minima.
  45.         Q.pop(); /// Scot minimul din heap.
  46.  
  47.         if(d == D[u]) { /// Verific daca nu cumva nodul era vechi si nu am nevoie de el.
  48.             for(i = 0; i < adjList[u].size(); i++) { /// Trec prin toti vecinii.
  49.                 v = adjList[u][i].other; /// v este vecinul nodului u.
  50.                 c = adjList[u][i].cost; /// c este costul muchiei (u, v).
  51.  
  52.                 if(D[v] > d + c) { /// Daca distanta pana la v curenta este mai mica decat d + c
  53.                     D[v] = d + c; /// Distanta pana la v devine egala cu d + c
  54.                     Q.push(Node{v, D[v]}); /// Introduc in heap v, cu distanta D[v].
  55.                 }
  56.             }
  57.         }
  58.     }
  59. }
  60.  
  61.  
  62. int main() {
  63.     int i, u, v, c;
  64.  
  65.     in >> n >> m;
  66.     for(i = 1; i <= m; i++) {
  67.         in >> u >> v >> c; /// Muchie orientata intre u si v, de cost c.
  68.         adjList[u].push_back(Edge{v, c}); /// Veciunul este v, costul muchiei este c.
  69.     }
  70.  
  71.     dijkstra(1); /// Pornim dijkstra cu sursa 1.
  72.     for(i = 2; i <= n; i++) {
  73.         if(D[i] == INF) {
  74.             D[i] = 0; /// Respectam conditia din enunt - un nod la care nu s-a ajuns este marcat 0.
  75.         }
  76.         out << D[i] << ' ';
  77.  
  78.     }
  79.     out << '\n';
  80.  
  81.     return 0;
  82. }
  83.  
  84.  
  85. /** Linkuri sumplimentare:
  86.         1. priority_queue si ce face - http://www.cplusplus.com/reference/queue/priority_queue/
  87.         2. algoritmul lui Dijkstra explicat si pe Wikipedia - https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
  88.     Baga codul in Code::Blocks, se va vedea mai bine sintaxa.
  89. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement