Advertisement
Tvor0zhok

Graphs Project

May 4th, 2021
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.42 KB | None | 0 0
  1. //подключаем заголовочные файлы и настраиваем работу с пространством имен
  2. #include <iostream> // для ввода и вывода данных
  3. #include <fstream> // для работы с файлами
  4. #include <vector> // для работы с вектором (динамическим массивом)
  5. #include <string> // для работы со строками (текстовыми данными)
  6. #include <queue> // для работы с очередью (структурой данных)
  7. using namespace std; // пространство имен
  8.  
  9. // в программе для того чтобы вместо одного длинного выражения писать другое, короткое
  10. typedef pair <int, int> ii;
  11. typedef vector <int> vi;
  12. typedef vector <ii> vii;
  13.  
  14. // переменная - константа, обозначающая в программе "бесконечноть"
  15. const int INF = 1e9 + 7;
  16.  
  17. // головная функция (здесь реализация нашей основной программы)
  18. int main()
  19. {
  20. // V - число вершин в графе (число городов)
  21. // s - число, обозначающее порядковый номер города в таблице (считаем с НУЛЯ)
  22. // w - переменная, в которую мы будем по циклу записывать данные из таблицы (расстояние между городами)
  23. int V = 11, s = 7, w;
  24.  
  25. // создаем вектор - массив списков и вектор городов
  26. vector <vii> AdjList;
  27. vector <string> cities(V);
  28.  
  29. // создаем файловый поток вывода данных из файла
  30. ifstream fin ("graphs.txt");
  31.  
  32. // "конструируем" все элементы вектора AdjList
  33. AdjList.assign(V, vii());
  34.  
  35. // по циклу выводим из файла первую строку с именами городов и вводим их в вектор
  36. for (int i = 0; i < V; i++)
  37. fin >> cities[i];
  38.  
  39. // по циклу выводим из файла оставшиеся данные
  40. for (int i = 0; i < V; ++i)
  41. {
  42. // сюда записываются города как первые элементы в строке, они нам НЕ НУЖНЫ, города мы уже записали
  43. string name; fin >> name;
  44.  
  45. // здесь в w записываются данные из таблицы
  46. for (int j = 0; j < V; ++j)
  47. {
  48. fin >> w;
  49.  
  50. // в скобках w <=> w != 0
  51. if (w) AdjList[i].push_back(ii(j, w));
  52. }
  53. }
  54.  
  55. ////////////////////////////////////////////////////////////////////
  56. ///
  57. /// АЛГОРИТМ ДЕЙКСТРЫ
  58. ///
  59. ////////////////////////////////////////////////////////////////////
  60.  
  61. // объявляем вектор, содержащий расстояния от вершины S до всех других вершин в графе
  62. // расстояние от S до S равно 0
  63. vi dist(V, INF); dist[s] = 0;
  64.  
  65. // вектор путей из Саратова до определенного города
  66. vector <vector <string>> ways(V);
  67.  
  68. // создаем особую структуру - приоритетную очередь, добавляем в нее первый элемент - пару (0, s)
  69. priority_queue <ii, vector<ii>, greater<ii>> pq; pq.push(ii(0, s));
  70.  
  71. // цикл работает до тех пока очередь НЕ пуста
  72. while (!pq.empty())
  73. {
  74. // создаем пару front, в нее записываем начало очереди (ее первый элемент), удаляем пару из очереди
  75. ii front = pq.top(); pq.pop();
  76.  
  77. // в эти переменные записываем первый и второй элементы пары front соответственно
  78. int d = front.first, u = front.second;
  79.  
  80. // если условие выполняется переходим к следующей итерации в цикле
  81. if (d > dist[u]) continue;
  82.  
  83. // по циклу проводим следующие действия
  84. for (int j = 0; j < AdjList[u].size(); j++)
  85. {
  86. // создаем пару v = (j, w), где w - расстояние от u до j
  87. ii v = AdjList[u][j];
  88.  
  89. // если условие выполняется, то выполяем следующие действия
  90. if (dist[u] + v.second < dist[v.first])
  91. {
  92. // записываем в dist[v.first] более малое расстояние, которое нашлось при выполнении программы
  93. dist[v.first] = dist[u] + v.second;
  94.  
  95. // добавляем в очередь новую пару
  96. pq.push(ii(dist[v.first], v.first));
  97.  
  98. // находим новый путь от вершины u до u[j]
  99. ways[v.first] = ways[u]; ways[v.first].push_back(cities[u]);
  100. }
  101. }
  102. }
  103.  
  104. // завершаем все пути прибытием в нужный пункт
  105. for (int i = 0; i < V; ++i)
  106. ways[i].push_back(cities[i]);
  107.  
  108. // Выводим ответ на экран
  109. cout << "The distance from " << cities[s] << " to " << cities[2] << " is " << dist[2] << " km.";
  110.  
  111. cout << "\nThe way: ";
  112.  
  113. // Выводим путь от Саратова до Москвы
  114. for (int i = 0; i < ways[2].size() - 1; ++i)
  115. cout << ways[2][i] << " - ";
  116.  
  117. cout << ways[2][ways[2].size() - 1];
  118.  
  119. // Закрываем поток (работу с файлом)
  120. fin.close();
  121. return 0;
  122. }
  123.  
  124. //graphs.txt
  125. Kursk Lipetsk Moscow Orel Penza Ryazan Saransk Saratov Tambov Tula Voronezh
  126. Kursk 0 0 0 164 0 0 0 0 0 0 227
  127. Lipetsk 0 0 437 294 0 265 0 0 135 292 126
  128. Moscow 0 437 0 0 0 199 0 0 459 183 516
  129. Orel 164 294 0 0 0 0 0 0 0 181 347
  130. Penza 0 0 0 0 0 443 148 232 289 0 0
  131. Ryazan 0 265 199 0 443 0 449 0 288 185 0
  132. Saransk 0 0 0 0 148 449 0 0 0 0 0
  133. Saratov 0 0 0 0 232 0 0 0 391 0 511
  134. Tambov 0 135 459 0 289 288 0 391 0 369 221
  135. Tula 0 292 183 181 0 185 0 0 369 0 345
  136. Voronezh 227 126 516 347 0 0 0 511 221 345 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement