Advertisement
Tvor0zhok

Графы веса (new)

Nov 27th, 2022
958
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 21.67 KB | None | 0 0
  1. #pragma once
  2. #include <algorithm>
  3. #include <iostream>
  4. #include <iomanip>
  5. #include <fstream>
  6. #include <utility>
  7. #include <vector>
  8. #include <queue>
  9. #include <map>
  10. #include <set>
  11. using namespace std;
  12.  
  13. const double INF = 1e9 + 7;
  14.  
  15. /// <summary>
  16. /// Граф
  17. /// </summary>
  18. /// <typeparam name="Vertice"> тип вершин графа </typeparam>
  19. /// <typeparam name="Edge"> тип ребер графа (int по умолчанию) </typeparam>
  20. template <class Vertice, class Edge = int>
  21. class Graph
  22. {
  23.     /// <summary>
  24.     /// Количество вершин и ребер в графе
  25.     /// </summary>
  26.     int _N = 0, _M = 0;
  27.  
  28.     /// <summary>
  29.     /// Критерий ориентированности и взвешенности графа
  30.     /// </summary>
  31.     bool IsDirected = false, IsWeighted = false;
  32.  
  33.     /// <summary>
  34.     /// Список смежности графа
  35.     /// </summary>
  36.     map <Vertice, map<Vertice, Edge>> graph;
  37.  
  38. public:
  39.  
  40.     /// <summary>
  41.     /// Конструктор по умолчанию
  42.     /// </summary>
  43.     Graph() {};
  44.  
  45.     /// <summary>
  46.     /// Конструктор, создающий пустой граф, определяющий
  47.     /// ориентированность и взвешенность графа
  48.     /// </summary>
  49.     /// <param name="direction"> критерий ориентированности </param>
  50.     /// <param name="weighting"> критерий взвешенности </param>
  51.     Graph(string direction, string weighting)
  52.     {
  53.         if (direction == "directed") IsDirected = true;
  54.         if (weighting == "weighted") IsWeighted = true;
  55.     }
  56.  
  57.     /// <summary>
  58.     /// Конструктор, считывающий информацию из файла
  59.     /// или из консоли (stdin)
  60.     /// </summary>
  61.     /// <param name="filePath"> путь к файлу или ключевое слово stdin </param>
  62.     Graph(string filePath)
  63.     {
  64.         ifstream fin;
  65.  
  66.         if (filePath == "stdin") fin = ifstream(stdin);
  67.         else fin = ifstream(filePath);
  68.  
  69.         string cmd, direction, weighting;
  70.         fin >> cmd >> direction >> weighting;
  71.  
  72.         *this = Graph(direction, weighting);
  73.  
  74.         fin >> cmd >> _N;
  75.  
  76.         for (int i = 0; i < _N; ++i)
  77.         {
  78.             Vertice v; fin >> v;
  79.             graph.insert(pair<Vertice, map<Vertice, Edge>>(v, map<Vertice, Edge>()));
  80.         }
  81.  
  82.         fin >> cmd >> _M;
  83.  
  84.         for (int i = 0; i < _M; ++i)
  85.         {
  86.             Vertice u, v; Edge w; fin >> u >> v;
  87.  
  88.             if (!IsWeighted) w = 1;
  89.             else fin >> w;
  90.  
  91.             graph[u].insert(pair<Vertice, Edge>(v, w));
  92.             if (!IsDirected) graph[v].insert(pair<Vertice, Edge>(u, w));
  93.         }
  94.  
  95.         if (filePath != "stdin") fin.close();
  96.     }
  97.  
  98.     /// <summary>
  99.     /// Количество вершин графа
  100.     /// </summary>
  101.     /// <returns> количество вершин графа </returns>
  102.     int n() { return _N; }
  103.  
  104.     /// <summary>
  105.     /// Количество ребер графа
  106.     /// </summary>
  107.     /// <returns> количество ребер графа </returns>
  108.     int m() { return _M; }
  109.  
  110.     /// <summary>
  111.     /// Метод, выдающий информацию об
  112.     /// ориентированности графа
  113.     /// </summary>
  114.     /// <returns> true, если граф ориентированный, иначе - false </returns>
  115.     bool isDirected() { return IsDirected; }
  116.  
  117.     /// <summary>
  118.     /// Метод, выдающий информацию о
  119.     /// взвешенности графа
  120.     /// </summary>
  121.     /// <returns> true, если граф взвешенный, иначе - false </returns>
  122.     bool isWeighted() { return IsWeighted; }
  123.  
  124.     /// <summary>
  125.     /// Метод, возращающий список смежности графа
  126.     /// </summary>
  127.     /// <returns> список смежности графа </returns>
  128.     map<Vertice, map<Vertice, Edge>> edges() { return graph; }
  129.  
  130.     /// <summary>
  131.     /// Добавление вершины в граф
  132.     /// </summary>
  133.     /// <param name="v"> добавляемая в граф вершина </param>
  134.     void addVertice(Vertice v)
  135.     {
  136.         try
  137.         {
  138.             if (graph.find(v) != graph.end()) throw "Добавление вершины: заданная вершина уже есть в графе";
  139.             else
  140.             {
  141.                 ++_N;
  142.                 graph.insert(pair<Vertice, map<Vertice, Edge>>(v, map<Vertice, Edge>()));
  143.             }
  144.         }
  145.         catch (const char* msg)
  146.         {
  147.             cout << msg << "\n";
  148.         }
  149.     }
  150.  
  151.     /// <summary>
  152.     /// Удаление вершины из графа
  153.     /// </summary>
  154.     /// <param name="v"> удаляемая из графа вершина </param>
  155.     void removeVertice(Vertice v)
  156.     {
  157.         try
  158.         {
  159.             if (graph.find(v) == graph.end()) throw "Удаление вершины: в графе отсутствует заданная вершина";
  160.             else
  161.             {
  162.                 --_N; _M -= graph[v].size();
  163.  
  164.                 graph.erase(v);
  165.  
  166.                 for (auto p : graph)
  167.                     if (graph[p.first].find(v) != graph[p.first].end())
  168.                     {
  169.                         if (IsDirected) --_M;
  170.                         graph[p.first].erase(v);
  171.                     }
  172.             }
  173.         }
  174.         catch (const char* msg)
  175.         {
  176.             cout << msg << "\n";
  177.         }
  178.     }
  179.  
  180.     /// <summary>
  181.     /// Добавление ребра в граф
  182.     /// </summary>
  183.     /// <param name="u"> первая вершина ребра </param>
  184.     /// <param name="v"> вторая вершина ребра </param>
  185.     /// <param name="w"> вес ребра (для невзвешенных графов w = 1) </param>
  186.     void addEdge(Vertice u, Vertice v, Edge w)
  187.     {
  188.         try
  189.         {
  190.             if (graph.find(u) == graph.end() || graph.find(v) == graph.end()) throw "Добавление ребра: в графе отсутствует(ют) заданная(ые) вершина(ы)";
  191.             else if (!IsDirected && u == v) throw "Добавление ребра: невозможно добавить петлю в неориентированный граф";
  192.             else if (graph[u].find(v) != graph[u].end()) throw "Добавление ребра: заданное ребро уже есть в графе";
  193.             else
  194.             {
  195.                 ++_M;
  196.                 graph[u][v] = w;
  197.                 if (!IsDirected) graph[v][u] = w;
  198.             }
  199.         }
  200.         catch (const char* msg)
  201.         {
  202.             cout << msg << "\n";
  203.         }
  204.     }
  205.  
  206.     /// <summary>
  207.     /// Удаление ребра из графа
  208.     /// </summary>
  209.     /// <param name="u"> первая вершина ребра </param>
  210.     /// <param name="v"> вторая вершина ребра </param>
  211.     void removeEdge(Vertice u, Vertice v)
  212.     {
  213.         try
  214.         {
  215.             if (graph.find(u) == graph.end() || graph.find(v) == graph.end()) throw "Удаление ребра: в графе отсутствует(ют) заданная(ые) вершина(ы)";
  216.             else
  217.             {
  218.                 if (graph[u].find(v) == graph[u].end()) throw "Удаление ребра: в графе отсутствует заданное ребро";
  219.                 else
  220.                 {
  221.                     --_M;
  222.                     graph[u].erase(v);
  223.                     if (!IsDirected) graph[v].erase(u);
  224.                 }
  225.             }
  226.         }
  227.         catch (const char* msg)
  228.         {
  229.             cout << msg << "\n";
  230.         }
  231.     }
  232.  
  233.     /// <summary>
  234.     /// Очищение графа (ориентированность
  235.     /// и взвешенность остаются прежними)
  236.     /// </summary>
  237.     void clear()
  238.     {
  239.         _N = 0; _M = 0;
  240.         graph.clear();
  241.     }
  242.  
  243.     /// <summary>
  244.     /// Вывод информации о графе в файл или
  245.     /// на консоль (stdout)
  246.     /// </summary>
  247.     /// <param name="filePath"> путь к файлу или ключевое слово stdout </param>
  248.     void print(string filePath)
  249.     {
  250.         ofstream fout;
  251.  
  252.         if (filePath == "stdout") fout = ofstream(stdout);
  253.         else fout = ofstream(filePath);
  254.  
  255.         if (filePath != "stdout")
  256.         {
  257.             fout << "GRAPH ";
  258.  
  259.             if (IsDirected) fout << "directed ";
  260.             else fout << "undirected ";
  261.  
  262.             if (IsWeighted) fout << "weighted\n";
  263.             else fout << "unweighted\n";
  264.  
  265.             fout << "VERTICES: " << _N << "\n";
  266.  
  267.             for (auto p : graph)
  268.                 fout << p.first << "\n";
  269.  
  270.             fout << "EDGES: " << _M << "\n";
  271.  
  272.             for (auto p1 : graph)
  273.             {
  274.                 Vertice u = p1.first;
  275.  
  276.                 for (auto p2 : p1.second)
  277.                 {
  278.                     Vertice v = p2.first; Edge w = p2.second;
  279.  
  280.                     if (IsDirected || u < v)
  281.                     {
  282.                         fout << u << " " << v << " ";
  283.                         if (IsWeighted) fout << w;
  284.                         fout << "\n";
  285.                     }
  286.                 }
  287.             }
  288.  
  289.             fout.close();
  290.         }
  291.         else
  292.         {
  293.             fout << "GRAPH ";
  294.  
  295.             if (IsDirected) fout << "directed ";
  296.             else fout << "undirected ";
  297.  
  298.             if (IsWeighted) fout << "weighted\n";
  299.             else fout << "unweighted\n";
  300.  
  301.             fout << "VERTICES: " << _N << "\n";
  302.  
  303.             for (auto p : graph)
  304.                 fout << p.first << "\n";
  305.  
  306.             fout << "EDGES: " << _M << "\n";
  307.  
  308.             for (auto p1 : graph)
  309.             {
  310.                 Vertice u = p1.first;
  311.  
  312.                 fout << u << ": ";
  313.  
  314.                 for (auto p2 : p1.second)
  315.                 {
  316.                     Vertice v = p2.first; Edge w = p2.second;
  317.  
  318.                     if (!IsWeighted) fout << v << " ";
  319.                     else fout << "(" << v << ", " << w << ") ";
  320.                 }
  321.  
  322.                 fout << "\n";
  323.             }
  324.         }
  325.     }
  326. };
  327.  
  328. /// <summary>
  329. /// Тройка: длина пути, путь, последняя вершина в пути
  330. /// </summary>
  331. /// <typeparam name="Vertice"> тип вершин графа </typeparam>
  332. /// <typeparam name="Edge"> тип ребер графа </typeparam>
  333. template <class Vertice, class Edge>
  334. struct triple
  335. {
  336.     Edge dist; map<Vertice, int> order; Vertice last;
  337.  
  338.     triple() {}
  339.     triple(Edge d, map<Vertice, int> o, Vertice l) : dist(d), order(o), last(l) {}
  340.  
  341.     bool operator < (const triple& t) const { return dist < t.dist; }
  342.     bool operator > (const triple& t) const { return dist > t.dist; }
  343. };
  344.  
  345. /// <summary>
  346. /// Алгоритм Дейкстры поиска кратчайшего пути
  347. /// от одной вершины до всех других вершин
  348. /// </summary>
  349. /// <typeparam name="Vertice"> тип вершин графа </typeparam>
  350. /// <typeparam name="Edge"> тип ребер графа </typeparam>
  351. /// <param name="edges"> список смежности графа </param>
  352. /// <param name="s"> стартовая вершина </param>
  353. /// <param name="t"> конечная вершина </param>
  354. /// <param name="k"> количество путей </param>
  355. /// <param name="ways"> восстановление путей </param>
  356. template <class Vertice, class Edge>
  357. void Dijkstra(map<Vertice, map<Vertice, Edge>> &edges, Vertice s, Vertice t, int k, map<Vertice, priority_queue<triple<Vertice, Edge>>> &ways)
  358. {
  359.     for (auto p : edges)
  360.     {
  361.         Vertice u = p.first;
  362.         ways[u] = priority_queue<triple<Vertice, Edge>>();
  363.     }
  364.  
  365.     priority_queue <triple<Vertice, Edge>, vector <triple<Vertice, Edge>>, greater<triple<Vertice, Edge>>> pq;
  366.    
  367.     map <Vertice, int> ord; ord[s] = 0;
  368.     pq.push(triple<Vertice, Edge>(0, ord, s));
  369.  
  370.     while (!pq.empty())
  371.     {
  372.         Edge d = pq.top().dist; map<Vertice, int> cur_ord = pq.top().order;
  373.         Vertice u = pq.top().last; pq.pop();
  374.  
  375.         if (ways[u].size() >= k && d > ways[u].top().dist) continue;
  376.  
  377.         for (auto p : edges[u])
  378.         {
  379.             Vertice v = p.first; Edge w = p.second;
  380.  
  381.             if (cur_ord.count(v)) continue;
  382.  
  383.             if (ways[v].size() < k)
  384.             {
  385.                 auto new_ord = cur_ord;
  386.                 new_ord[v] = new_ord.size();
  387.                 triple<Vertice, Edge> to = triple<Vertice, Edge>(d + w, new_ord, v);
  388.                 ways[v].push(to);
  389.                 pq.push(to);
  390.             }
  391.             else if (d + w < ways[v].top().dist)
  392.             {
  393.                 ways[v].pop();
  394.                 auto new_ord = cur_ord;
  395.                 new_ord[v] = new_ord.size();
  396.                 triple<Vertice, Edge> to = triple<Vertice, Edge>(d + w, new_ord, v);
  397.                 ways[v].push(to);
  398.                 pq.push(to);
  399.             }
  400.         }
  401.     }
  402. }
  403.  
  404. /// <summary>
  405. /// Восстановление путей по предкам
  406. /// </summary>
  407. /// <typeparam name="Vertice"> тип вершин графа </typeparam>
  408. /// <typeparam name="Edge"> тип ребер графа </typeparam>
  409. /// <param name="edges"> список смежности графа </param>
  410. /// <param name="parents"> список предков вершин графа </param>
  411. /// <param name="s"> начало пути </param>
  412. /// <param name="cur"> текущая вершина пути </param>
  413. /// <param name="cnt"> порядковый номер пути </param>
  414. /// <param name="path"> история пути </param>
  415. template <class Vertice, class Edge>
  416. void FindPaths(map<Vertice, map<Vertice, Edge>> &edges, map<Vertice, set<Vertice>>& parents, Vertice s, Vertice cur, int& cnt, int k, vector<Vertice> &path)
  417. {
  418.     if (cnt == k) return;
  419.    
  420.     path.push_back(cur);
  421.  
  422.     if (cur == s)
  423.     {
  424.         cout << ++cnt << ": ";
  425.  
  426.         for (int i = path.size() - 1; i > 0; --i)
  427.         {
  428.             Vertice u = path[i], v = path[i - 1]; Edge w = edges[u][v];
  429.  
  430.             cout << u << " --(" << w << ")--> ";
  431.         }
  432.  
  433.         cout << path[0] << "\n";
  434.     }
  435.     else
  436.     {
  437.         for (auto p : parents[cur])
  438.             FindPaths<Vertice, Edge>(edges, parents, s, p, cnt, k, path);
  439.     }
  440.  
  441.     path.pop_back();
  442. }
  443.  
  444. /// <summary>
  445. /// Алгоритм Беллмана-Форда поиска кратчайшего пути
  446. /// между двумя заданными вершинами
  447. /// </summary>
  448. /// <typeparam name="Vertice"> тип вершин графа </typeparam>
  449. /// <typeparam name="Edge"> тип ребер графа </typeparam>
  450. /// <param name="edges"> список смежности графа </param>
  451. /// <param name="s"> начальная вершина </param>
  452. /// <param name="t"> конечная вершина </param>
  453. /// <param name="parents"> список предков вершин графа </param>
  454. /// <returns> расстояние между вершинами s и t </returns>
  455. template <class Vertice, class Edge>
  456. Edge Bellman(map<Vertice, map<Vertice, Edge>>& edges, Vertice s, Vertice t, map<Vertice, set<Vertice>> &parents)
  457. {
  458.     map<Vertice, Edge> dist;
  459.  
  460.     for (auto p : edges)
  461.     {
  462.         Vertice u = p.first;
  463.         dist[u] = INF;
  464.     }
  465.  
  466.     dist[s] = 0;
  467.  
  468.     for (int i = 0; i < edges.size() - 1; ++i)
  469.     {
  470.         bool flag = false;
  471.  
  472.         for (auto p1 : edges)
  473.         {
  474.             Vertice u = p1.first;
  475.  
  476.             if (dist[u] == INF) continue;
  477.  
  478.             for (auto p2 : edges[u])
  479.             {
  480.                 Vertice v = p2.first; Edge w = p2.second;
  481.  
  482.                 if (dist[v] >= dist[u] + w)
  483.                 {
  484.                     if (dist[v] > dist[u] + w)
  485.                     {
  486.                         parents[v].clear();
  487.                         dist[v] = dist[u] + w;
  488.                         flag = true;
  489.                     }
  490.  
  491.                     parents[v].insert(u);
  492.                 }
  493.             }
  494.         }
  495.  
  496.         if (!flag) break;
  497.     }
  498.  
  499.     return dist[t];
  500. }
  501.  
  502. /// <summary>
  503. /// Задание IV a: поиск всех кратчайших путей
  504. /// между заданными вершинами s и t
  505. /// </summary>
  506. /// <typeparam name="Vertice"> тип вершин графа </typeparam>
  507. /// <typeparam name="Edge"> тип ребер графа </typeparam>
  508. /// <param name="g"> граф </param>
  509. /// <param name="s"> начальная вершина </param>
  510. /// <param name="t"> конечная вершина </param>
  511. template <class Vertice, class Edge>
  512. void AllShortestPaths(Graph<Vertice, Edge>& g, Vertice s, Vertice t)
  513. {
  514.     map<Vertice, map<Vertice, Edge>> edges = g.edges();
  515.     map<Vertice, set<Vertice>> parents;
  516.  
  517.     try
  518.     {
  519.         if (edges.find(s) == edges.end()) throw "Задание IV a: вершины s нет в графе";
  520.         else if (edges.find(t) == edges.end()) throw "Задание IV a: вершины t нет в графе";
  521.         else
  522.         {
  523.             Edge length = Bellman(edges, s, t, parents);
  524.  
  525.             if (parents[t].size() == 0) cout << "Вершины s = " << s << " и t = " << t << " находятся в разных компонентах связности\n";
  526.             else
  527.             {
  528.                 cout << "Всевозможные пути (длины " << length << ")\n";
  529.  
  530.                 int cnt = 0;
  531.                 vector<Vertice> path;
  532.                 FindPaths<Vertice, Edge>(edges, parents, s, t, cnt, INF, path);
  533.  
  534.                 cout << "Итого: " << cnt << " различных кратчайших путей\n";
  535.             }
  536.         }
  537.     }
  538.     catch (const char* msg)
  539.     {
  540.         cout << msg << "\n";
  541.     }
  542. }
  543.  
  544. /// <summary>
  545. /// Задание IV b: поиск k кратчайших путей
  546. /// между заданными вершинами s и t
  547. /// </summary>
  548. /// <typeparam name="Vertice"> тип вершин графа </typeparam>
  549. /// <typeparam name="Edge"> тип ребер графа </typeparam>
  550. /// <param name="g"> граф </param>
  551. /// <param name="s"> начальная вершина </param>
  552. /// <param name="t"> конечная вершина </param>
  553. /// <param name="k"> количество кратчайших путей </param>
  554. template <class Vertice, class Edge>
  555. void KShortestPaths(Graph<Vertice, Edge>& g, Vertice s, Vertice t, int k)
  556. {
  557.     map<Vertice, priority_queue<triple<Vertice, Edge>>> ways;
  558.     map <Vertice, map<Vertice, Edge>> edges = g.edges();
  559.  
  560.     try
  561.     {
  562.         if (edges.find(s) == edges.end()) throw "Задание IV b: вершины s нет в графе";
  563.         else if (edges.find(t) == edges.end()) throw "Задание IV b: вершины t нет в графе";
  564.         else if (k <= 0) throw "Задание IV b: Значение k должно быть положительным";
  565.         else
  566.         {
  567.             Dijkstra(edges, s, t, k, ways);
  568.  
  569.             if (ways[t].size() == 0) cout << "Вершины s = " << s << " и t = " << t << " находятся в разных компонентах связности\n";
  570.             else
  571.             {
  572.                 vector<triple<Vertice, Edge>> ans;
  573.  
  574.                 while (!ways[t].empty())
  575.                 {
  576.                     ans.push_back(ways[t].top());
  577.                     ways[t].pop();
  578.                 }
  579.  
  580.                 int cnt = 1;
  581.  
  582.                 for (int i = ans.size() - 1; i >= 0 && cnt <= k; --i, ++cnt)
  583.                 {
  584.                     cout << "Путь №" << cnt << ": длина = " << ans[i].dist << "\n";
  585.  
  586.                     vector <Vertice> way(ans[i].order.size());
  587.  
  588.                     for (auto p : ans[i].order)
  589.                         way[p.second] = p.first;
  590.  
  591.                     for (int i = 0; i < way.size() - 1; ++i)
  592.                         cout << way[i] << " ---(" << edges[way[i]][way[i + 1]] << ")--> ";
  593.  
  594.                     cout << way.back() << "\n\n";
  595.                 }
  596.  
  597.                 if (cnt < k) cout << "В графе не нашлось k = " << k << " путей между вершинами s и t\n";
  598.             }
  599.         }
  600.     }
  601.     catch (const char* msg)
  602.     {
  603.         cout << msg << "\n";
  604.     }
  605. }
  606.  
  607. /// <summary>
  608. /// Алгоритм Флойда поиска кратчайших путей
  609. /// между всеми парами вершин
  610. /// </summary>
  611. /// <typeparam name="Vertice"> тип вершин графа </typeparam>
  612. /// <typeparam name="Edge"> тип ребер графа </typeparam>
  613. /// <param name="mat"> матрица кратчайших расстояний </param>
  614. /// <param name="vertices"> вершины графа </param>
  615. template <class Vertice, class Edge>
  616. void Floyd(map<Vertice, map<Vertice, Edge>>& mat, vector<Vertice>& vertices)
  617. {
  618.     for (auto k : vertices)
  619.     {
  620.         map<Vertice, map<Vertice, Edge>> res = mat;
  621.  
  622.         for (auto u : vertices)
  623.             for (auto v : vertices)
  624.                 if (mat[u][k] != INF && mat[k][v] != INF)
  625.                     res[u][v] = min(mat[u][v], mat[u][k] + mat[k][v]);
  626.  
  627.         mat = res;
  628.     }
  629. }
  630.  
  631. /// <summary>
  632. /// Задание IV c: поиск всех пар вершин, длина
  633. /// пути между которыми может быть сколь угодно малой
  634. /// </summary>
  635. /// <typeparam name="Vertice"> тип вершин графа </typeparam>
  636. /// <typeparam name="Edge"> тип ребер графа </typeparam>
  637. /// <param name="g"> граф </param>
  638. template <class Vertice, class Edge>
  639. void AllPairs(Graph<Vertice, Edge>& g)
  640. {
  641.     vector<Vertice> vertices;
  642.     map <Vertice, map<Vertice, Vertice>> ans;
  643.     map <Vertice, map<Vertice, Edge>> edges = g.edges();
  644.  
  645.     for (auto p : edges)
  646.     {
  647.         Vertice v = p.first;
  648.         vertices.push_back(v);
  649.         ans[v] = map<Vertice, Vertice>();
  650.     }
  651.  
  652.     for (auto s : vertices)
  653.     {
  654.         vector <Vertice> from_vertices;
  655.         vector <Vertice> to_vertices;
  656.  
  657.         for (auto p : edges[s])
  658.             from_vertices.push_back(p.first);
  659.  
  660.         for (auto p1 : edges)
  661.         {
  662.             Vertice u = p1.first;
  663.  
  664.             for (auto p2 : edges[u])
  665.             {
  666.                 if (p2.first == s) to_vertices.push_back(u);
  667.             }
  668.         }
  669.  
  670.         Graph<Vertice, Edge> gs = g; gs.removeVertice(s);
  671.  
  672.         map<Vertice, map<Vertice, Edge>> mat;
  673.         map <Vertice, map<Vertice, Edge>> edges = gs.edges();
  674.  
  675.         for (auto u : vertices)
  676.             if (u != s)
  677.                 for (auto v : vertices)
  678.                     if (v != s) mat[u][v] = (u == v || edges[u].count(v) == 0) ? INF : edges[u][v];
  679.  
  680.         vector <Vertice> new_vertices;
  681.  
  682.         for (auto v : vertices)
  683.             if (v != s) new_vertices.push_back(v);
  684.  
  685.         Floyd(mat, new_vertices);
  686.  
  687.         set <Vertice> in_cycle;
  688.  
  689.         for (auto v : new_vertices)
  690.             if (mat[v][v] < 0) in_cycle.insert(v);
  691.  
  692.         for (auto u : from_vertices)
  693.             for (auto v : to_vertices)
  694.                 for (auto k : in_cycle)
  695.                     if (mat[u][k] != INF && mat[k][v] != INF) ans[s][s] = k;
  696.        
  697.         for (auto t : vertices)
  698.             if (t != s)
  699.             {
  700.                 map<Vertice, map<Vertice, Edge>> mat;
  701.                 map <Vertice, map<Vertice, Edge>> edges = gs.edges();
  702.                 vector <Vertice> to_vertices;
  703.  
  704.                 for (auto p1 : edges)
  705.                 {
  706.                     Vertice u = p1.first;
  707.  
  708.                     for (auto p2 : edges[u])
  709.                     {
  710.                         if (p2.first == t) to_vertices.push_back(u);
  711.                     }
  712.                 }
  713.  
  714.                 Graph<Vertice, Edge> gst = gs; gst.removeVertice(t);
  715.  
  716.                 edges = gst.edges();
  717.  
  718.                 for (auto u : vertices)
  719.                     if (u != s && u != t)
  720.                         for (auto v : vertices)
  721.                             if (v != s && v != t)
  722.                                 mat[u][v] = (u == v || edges[u].count(v) == 0) ? INF : edges[u][v];
  723.  
  724.                 vector <Vertice> new_vertices;
  725.  
  726.                 for (auto v : vertices)
  727.                     if (v != s && v != t) new_vertices.push_back(v);
  728.                
  729.                 Floyd(mat, new_vertices);
  730.  
  731.                 set <Vertice> in_cycle;
  732.  
  733.                 for (auto v : new_vertices)
  734.                     if (mat[v][v] < 0) in_cycle.insert(v);
  735.  
  736.                 for (auto u : from_vertices)
  737.                     if (u != t)
  738.                         for (auto v : to_vertices)
  739.                             if (v != s)
  740.                                 for (auto k : in_cycle)
  741.                                     if (mat[u][k] != INF && mat[k][v] != INF) ans[s][t] = k;
  742.             }
  743.     }
  744.  
  745.     cout << "    | ";
  746.  
  747.     for (auto v : vertices)
  748.         cout << left << setw(2) << v << " ";
  749.  
  750.     cout << "\n----+-";
  751.  
  752.     for (int i = 0; i < vertices.size(); ++i)
  753.         cout << "---";
  754.  
  755.     cout << "\n";
  756.  
  757.     for (auto u : vertices)
  758.     {
  759.         cout << " " << left << setw(2) << u << " | ";
  760.  
  761.         for (auto v : vertices)
  762.         {
  763.             if (ans[u].count(v) == 0) cout << "--" << " ";
  764.             else cout << left << setw(2) << ans[u][v] << " ";
  765.         }
  766.  
  767.         cout << "\n";
  768.     }
  769. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement