Advertisement
Guest User

PRIM (prototype)

a guest
Mar 29th, 2020
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.27 KB | None | 0 0
  1. #include <iostream>
  2. #include <queue>
  3. #include <vector>
  4. using namespace std;
  5.  
  6. int V, E; // Кол-во вершин и рёбер в графе соответственно
  7. vector<vector<int>> graph; // Список смежности исходного графа
  8. vector<vector<int>> mst; // Минимальное остовное дерево
  9. vector<vector<int>> weight; // Веса рёбер. weigt[i][j] - вес ребра (i,j)
  10. vector<int> d; // Расстояние от i-ой вершины до mst
  11. vector<int> p; // Предок i-ой вершины. У (p[i], i) минимальный вес(для mst)
  12. vector<int> q; // Приоритетная очередь, где ключ d[i]
  13. int mst_weight = 0;
  14.  
  15. /*----------- Заполнение списка смежности + ----------------------------------*/
  16. void read_graph() {
  17.   cin >> V >> E;
  18.  
  19.   graph.resize(V);
  20.   weight.assign(V, vector<int>(V, 100001));
  21.  
  22.   int begin, end, w; // Начальная вершина ребра, конечная, вес ребра
  23.   for (int i = 0; i < E; i++) {
  24.     cin >> begin >> end >> w;
  25.     graph[begin - 1].push_back(end - 1);
  26.     graph[end - 1].push_back(begin - 1); // Тк граф неориентированный
  27.     weight[begin - 1][end - 1] = w;
  28.     weight[end - 1][begin - 1] = w;
  29.   }
  30. }
  31. /*----------- Проверить есть ли ещё вершины в q ------------------------------*/
  32. bool q_empty() {
  33.   for (int i = 0; i < V; i++) // Идём по всей очереди
  34.     if (q[i] != -1) // если есть хоть одна вершина
  35.       return false; // то очередь не пустая
  36.   return true;
  37. }
  38. /*----------- Поиск вершины с минимальным расстоянием до остовного дерева ----*/
  39. int extract_min() {
  40.   int min = 0; // Индекс вершины с минимальным расстоянием до остовного дерева
  41.   for (int i = 1; i < V; i++) // Идём по всем вершинам
  42.     if (d[i] < d[min]) // и ищем минимальное расстояние до остовного дерева
  43.       min = i;
  44.   q[min] = -1; // Вершина с индексом min отработанна и её в очереди больше нет
  45.   d[min] = 100001; // Чтобы не выбирались новые вершины
  46.   return min;
  47. }
  48. /*----------- Проверить есть ли вершина в q ----------------------------------*/
  49. bool in_q(int vertex) { // Передаём индекс вершины
  50.   if (q[i] == -1) // Если вершина == -1 => её нет в очереди
  51.     return false;
  52.   return true;
  53. }
  54. /*----------- Алгоритм Прима -------------------------------------------------*/
  55. void prim_find_mst() {
  56.   mst.resize(V);       // В mst изначально ничего нет
  57.   d.assign(V, 100001); // Всем вершинам задаём бесконечно большое расстояние
  58.   p.assign(V, -1); // У всех вершин изначально нет родителя
  59.   d[0] = 0; // Вершина 0 стартовая и уже входит в mst
  60.  
  61.   q.resize(V);                // В q сейчас ровно V нулей
  62.   for (int j = 0; j < V; j++) // но надо чтобы было 0, 1, 2, ..., V-1
  63.     q[j] = j;
  64.  
  65.   int vertex = extract_min(); // Извлечётся вершина с индексом 0
  66.  
  67.   while (!q_empty()) { // Пока не пербрали все вершины
  68.     for (auto adjacent : graph[vertex]) // идём по всем вершинам смежным vertex
  69.       if (weight[vertex][adjacent] < d[adjacent] && in_q(adjacent)) {
  70.         d[adjacent] = weight[adjacent][vertex]; // Задаём расстояние и
  71.         p[adjacent] = vertex; // предка для смежной вершины
  72.       }
  73.  
  74.     vertex = extract_min();
  75.  
  76.     // mst[p[vertex]].push_back(vertex);
  77.     // mst[vertex].push_back(p[vertex]);
  78.     mst_weight += weight[p[vertex]][vertex];
  79.   }
  80.   cout << mst_weight << endl;
  81. }
  82. /*----------------------------------------------------------------------------*/
  83. int main() {
  84.  
  85.   freopen("spantree3.in", "r", stdin);
  86.   // freopen("spantree3.out", "w", stdout);
  87.  
  88.   read_graph();
  89.   prim_find_mst();
  90.  
  91.   return 0;
  92. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement