darya_leushkina

Untitled

Sep 3rd, 2019
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 24.41 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <map>
  4. #include <vector>
  5. #include <queue>
  6. #include <string>
  7. #include <algorithm>
  8.  
  9. using namespace std;
  10.  
  11. const int INF = 1000 * 1000 * 1000;
  12.  
  13. class Graph
  14. {
  15. public:
  16.     map<int, vector<pair<int, int>>> g;
  17.     bool directed;
  18.     bool weighted;
  19.     int s, t; // для сети
  20.  
  21.     Graph()
  22.     {
  23.         directed = false;
  24.         weighted = false;
  25.     }
  26.  
  27.     Graph(int source, int stock, const string& path)
  28.     { // сеть
  29.         s = source;
  30.         t = stock;
  31.         ifstream in(path.c_str());
  32.  
  33.         in >> directed >> weighted; // сначала в инпуте указывается, ориентирован и взвешен ли граф
  34.                                     // (0 если нет, 1 если да)
  35.  
  36.                                     /* Далее в инпуте указываются четыре команды:
  37.                                     +v i добавляет вершину i
  38.                                     -v i удаляет вершину i и все инцидентные ей ребра
  39.                                     +e i j w добавляет ребро (либо дугу) между i и j, и если граф взвешенный, делает его весом
  40.                                     w.
  41.                                     -e i j удаляет ребро между i и j
  42.                                     */
  43.         while (!in.eof())
  44.         {
  45.             string str;
  46.             in >> str;
  47.             if (str == "+v")
  48.             {
  49.                 int v;
  50.                 in >> v;
  51.                 add_vertex(v);
  52.             }
  53.             else if (str == "+e")
  54.             {
  55.                 int i, j, w = 1; // если граф не взвешен, по умолчанию весом ребра считаем 1.
  56.                 in >> i >> j;
  57.                 if (weighted)
  58.                 {
  59.                     in >> w;
  60.                 }
  61.                 add_edge(i, j, w);
  62.             }
  63.             else if (str == "-e")
  64.             {
  65.                 int i, j;
  66.                 in >> i >> j;
  67.                 remove_edge(i, j);
  68.             }
  69.             else if (str == "-v")
  70.             {
  71.                 int v;
  72.                 in >> v;
  73.                 remove_vertex(v);
  74.             }
  75.         }
  76.  
  77.         in.close();
  78.     }
  79.  
  80.     Graph(int n)
  81.     { // тестовый граф (будем создавать полный граф)
  82.         weighted = false;
  83.         directed = false;
  84.         for (int i = 0; i < n; i++)
  85.         {
  86.             add_vertex(i);
  87.             for (int j = 0; j < i; j++)
  88.             {
  89.                 add_edge(i, j, 1);
  90.             }
  91.         }
  92.     }
  93.  
  94.     Graph(const map<int, vector<pair<int, int>>>& a)
  95.     { // copy
  96.         g = a;
  97.     }
  98.  
  99.     Graph(const string& path)
  100.     { // read from file
  101.         ifstream in(path.c_str());
  102.  
  103.         in >> directed >> weighted; // сначала в инпуте указывается, ориентирован и взвешен ли граф
  104.                                     // (0 если нет, 1 если да)
  105.  
  106.                                     /* Далее в инпуте указываются четыре команды:
  107.                                     +v i добавляет вершину i
  108.                                     -v i удаляет вершину i и все инцидентные ей ребра
  109.                                     +e i j w добавляет ребро (либо дугу) между i и j, и если граф взвешенный, делает его весом
  110.                                     w.
  111.                                     -e i j удаляет ребро между i и j
  112.                                     */
  113.         while (!in.eof())
  114.         {
  115.             string s;
  116.             in >> s;
  117.             if (s == "+v")
  118.             {
  119.                 int v;
  120.                 in >> v;
  121.                 add_vertex(v);
  122.             }
  123.             else if (s == "+e")
  124.             {
  125.                 int i, j, w = 1; // если граф не взвешен, по умолчанию весом ребра считаем 1.
  126.                 in >> i >> j;
  127.                 if (weighted)
  128.                 {
  129.                     in >> w;
  130.                 }
  131.                 add_edge(i, j, w);
  132.             }
  133.             else if (s == "-e")
  134.             {
  135.                 int i, j;
  136.                 in >> i >> j;
  137.                 remove_edge(i, j);
  138.             }
  139.             else if (s == "-v")
  140.             {
  141.                 int v;
  142.                 in >> v;
  143.                 remove_vertex(v);
  144.             }
  145.         }
  146.  
  147.         in.close();
  148.     }
  149.  
  150.     ~Graph()
  151.     {
  152.         g.clear();
  153.     }
  154.  
  155.     void add_vertex(int v)
  156.     {
  157.         if (g.find(v) == g.end())
  158.         { // если вершины еще нет в графе, то добавляем
  159.             vector<pair<int, int>> tmp;
  160.             g[v] = tmp;
  161.         }
  162.     }
  163.  
  164.     void add_edge(int u, int v, int w)
  165.     {
  166.         if (g.find(u) == g.end() || g.find(v) == g.end())
  167.         { // если таких вершин нет - выходим
  168.             return;
  169.         }
  170.  
  171.         for (int i = 0; i < g[u].size(); i++)
  172.         {
  173.             if (g[u][i].first == v)
  174.             { // если ребро (u, v) уже существует, то выходим
  175.                 return;
  176.             }
  177.         }
  178.  
  179.         g[u].push_back(make_pair(v, w));
  180.  
  181.         if (!directed)
  182.         {
  183.             add_edge(v, u, w);
  184.         }
  185.     }
  186.  
  187.     void remove_edge(int u, int v)
  188.     {
  189.         if (g.find(u) == g.end() || g.find(v) == g.end())
  190.         {
  191.             return;
  192.         }
  193.         for (int i = 0; i < g[u].size(); i++)
  194.         { // ищем все ребра (u, v)
  195.             if (g[u][i].first == v)
  196.             {
  197.                 g[u].erase(g[u].begin() + i);
  198.             }
  199.         }
  200.  
  201.         if (!directed)
  202.         { // если граф неориентир, то надо так же удалить все ребра (v, u)
  203.             remove_edge(v, u);
  204.         }
  205.     }
  206.  
  207.     void remove_vertex(int v)
  208.     {
  209.         if (g.find(v) == g.end())
  210.         {
  211.             return;
  212.         }
  213.         g.erase(v);
  214.  
  215.         for (map<int, vector<pair<int, int>>>::iterator it = g.begin(); it != g.end(); it++)
  216.         { // после удаления вершины v проходимся по всем остальным вершинам i и
  217.             remove_edge((*it).first, v); // ищем все ребра типа (i, v) и удаляем их
  218.         }
  219.     }
  220.  
  221.     Graph transponate()
  222.     {
  223.         if (!directed)
  224.         {
  225.             return Graph(g);
  226.         }
  227.         Graph result;
  228.         result = Graph();
  229.         result.directed = true;
  230.         result.weighted = weighted;
  231.  
  232.         for (map<int, vector<pair<int, int>>>::iterator it = g.begin(); it != g.end(); it++)
  233.         {
  234.             result.add_vertex((*it).first);
  235.             for (int i = 0; i < int((*it).second.size()); i++)
  236.             {
  237.                 result.add_vertex(g[(*it).first][i].first);
  238.                 result.add_edge(g[(*it).first][i].first, (*it).first, g[(*it).first][i].second);
  239.             }
  240.         }
  241.  
  242.         return result;
  243.     }
  244.  
  245.     void print(string& path)
  246.     {
  247.         ofstream out;
  248.         out.open(path.c_str());
  249.  
  250.         cout << g.size() << endl; // количество вершин в графе
  251.         for (map<int, vector<pair<int, int>>>::iterator it = g.begin(); it != g.end(); it++)
  252.         {
  253.             for (int i = 0; i < int(((*it).second).size()); i++)
  254.             { // печатаем все ребра (если граф неориентированный, print напечатает ребра (i, j) и
  255.               // (j, i))
  256.                 out << (*it).first << " " << g[(*it).first][i].first;
  257.                 if (weighted)
  258.                 {
  259.                     out << " "
  260.                         << g[(*it).first][i].second; // добавляем вес ребра, если граф взвешен
  261.                 }
  262.                 out << endl;
  263.             }
  264.         }
  265.         out.close();
  266.     }
  267. };
  268.  
  269. class GraphFunctions
  270. {
  271. private:
  272.     Graph g;
  273.  
  274. public:
  275.     GraphFunctions()
  276.     {
  277.     }
  278.  
  279.     GraphFunctions(const Graph& graph)
  280.     {
  281.         g = graph;
  282.     }
  283.  
  284.     /* Задание 1b вариант 3.*/
  285.     Graph graph_union(Graph a)
  286.     {
  287.         Graph result;
  288.         result = Graph(); // создаем пустой граф
  289.  
  290.         if (a.directed != g.directed || a.weighted != g.weighted)
  291.         { // если графы не совпадают друг с другом, то вернуть пустой граф
  292.             return result;
  293.         }
  294.         result.directed = g.directed;
  295.         result.weighted = g.weighted;
  296.  
  297.         for (map<int, vector<pair<int, int>>>::iterator it = g.g.begin(); it != g.g.end(); it++)
  298.         {
  299.             result.add_vertex((*it).first);
  300.             for (int i = 0; i < int(((*it).second).size()); i++)
  301.             {
  302.                 result.add_edge((*it).first, g.g[(*it).first][i].first, g.g[(*it).first][i].second);
  303.             }
  304.         }
  305.         for (map<int, vector<pair<int, int>>>::iterator it = a.g.begin(); it != a.g.end(); it++)
  306.         {
  307.             result.add_vertex((*it).first);
  308.             for (int i = 0; i < int(((*it).second).size()); i++)
  309.             {
  310.                 result.add_edge((*it).first, a.g[(*it).first][i].first, a.g[(*it).first][i].second);
  311.             }
  312.         }
  313.  
  314.         return result;
  315.     }
  316.  
  317.  
  318.  
  319.     /* Задание 2 вариант 5.
  320.     https://e-maxx.ru/algo/connected_components. */
  321.     map<int, bool> empty_used()
  322.     {
  323.         map<int, bool> used;
  324.         for (map<int, vector<pair<int, int>>>::iterator it = g.g.begin(); it != g.g.end(); it++)
  325.         {
  326.             used[(*it).first] = false;
  327.         }
  328.         return used;
  329.     }
  330.  
  331.     void dfs1(int v, Graph& g, map<int, bool>& used, vector<int>& order)
  332.     {
  333.         used[v] = true;
  334.         for (int i = 0; i < g.g[v].size(); i++)
  335.         {
  336.             if (!used[g.g[v][i].first])
  337.             {
  338.                 dfs1(g.g[v][i].first, g, used, order);
  339.             }
  340.         }
  341.         order.push_back(v);
  342.     }
  343.  
  344.     void dfs2(int v, Graph& gt, map<int, bool>& used)
  345.     {
  346.         used[v] = true;
  347.         for (int i = 0; i < gt.g[v].size(); i++)
  348.         {
  349.             if (!used[gt.g[v][i].first])
  350.             {
  351.                 dfs2(gt.g[v][i].first, gt, used);
  352.             }
  353.         }
  354.     }
  355.  
  356.     int comp_count()
  357.     {
  358.         int result = 0;
  359.         Graph gt = g.transponate();
  360.         vector<int> order;
  361.  
  362.         map<int, bool> used = empty_used();
  363.         for (map<int, vector<pair<int, int>>>::iterator it = g.g.begin(); it != g.g.end(); it++)
  364.         {
  365.             /*Запускаем серию обходов в глубину графа G, которая возвращает
  366.             вершины в порядке увеличения времени выхода, т.е.некоторый список order.*/
  367.             if (!used[(*it).first])
  368.             {
  369.                 dfs1((*it).first, g, used, order);
  370.                 result++;
  371.             }
  372.         }
  373.         return result;
  374.     }
  375.  
  376.     /* Задание 3.
  377.     Алгоритм Прима:
  378.     https://ru.wikipedia.org/wiki/Алгоритм_Прима
  379.     */
  380.     Graph prim()
  381.     {
  382.         Graph mst;
  383.         mst = Graph();
  384.         mst.directed = false;
  385.         mst.weighted = true;
  386.  
  387.         map<int, bool> used; // индикатор, включена ли вершина в mst или нет.
  388.         map<int, int> min_w; // хранит вес наименьшего инцидентного ребра из вершины i
  389.         map<int, int> sel_e; // для вершины i содержит конец этого наименьшего ребра
  390.  
  391.         int start = -1;
  392.         for (map<int, vector<pair<int, int>>>::iterator it = g.g.begin(); it != g.g.end(); it++)
  393.         {
  394.             int v = (*it).first;
  395.             if (start == -1)
  396.             { // поскольку в алгоритме Прима в качестве начальной вершины выбирается любая
  397.                 start = v; // то для облегчения задачи выберем первую попавшуюся вершину
  398.             }
  399.             used[v] = false; // изначально все ребра не в mst
  400.             min_w[v] = INF; // расстояние до всех вершин неизвестно <=> равно бесконечности
  401.             sel_e[v] = -1; // исходя из строки выше, концы ребер неизвестны <=> равны -1
  402.         }
  403.  
  404.         min_w[start] = 0; // наименьший вес от стартовой вершины до стартовой = 0
  405.         for (map<int, vector<pair<int, int>>>::iterator it = g.g.begin(); it != g.g.end(); it++)
  406.         { // проходим по всем вершинам
  407.             int v = -1; // выбираем следующую вершину вне mst(наше дерево), которую включим в mst, с минимальным
  408.                         // весом (цикл ниже)
  409.             for (map<int, vector<pair<int, int>>>::iterator it = g.g.begin(); it != g.g.end(); it++)
  410.             {
  411.                 if (!used[(*it).first] && (v == -1 || min_w[(*it).first] < min_w[v]))
  412.                 {
  413.                     v = (*it).first;
  414.                 }
  415.             }
  416.             if (min_w[v] == INF)
  417.             {
  418.                 return Graph();
  419.             }
  420.  
  421.             used[v] = true; // добавляем вершину v в mst
  422.             if (sel_e[v] != -1)
  423.             { // если для вершины v уже посчитан конец наименьшего ребра
  424.                 mst.add_vertex(v);
  425.                 mst.add_vertex(sel_e[v]);
  426.                 mst.add_edge(v, sel_e[v], min_w[v]); // то добавляем это ребро в ответ
  427.             }
  428.             for (int i = 0; i < g.g[v].size(); i++)
  429.             { // для всех соседей v пересчитываем min_w и sel_e по возможности
  430.                 if (g.g[v][i].second < min_w[g.g[v][i].first])
  431.                 { // если вес ребра (v, сосед v) меньше значения в min_w
  432.                     min_w[g.g[v][i].first] = g.g[v][i].second; // то обновляем значение min_w
  433.                     sel_e[g.g[v][i].first]
  434.                         = v; // и для соседа v указываем концов наименьшего ребра само v
  435.                 }
  436.             }
  437.         }
  438.  
  439.         return mst;
  440.     }
  441.  
  442.  
  443.  
  444.     /* Задание 4а. По условию подходит алгоритм Дейкстра - он не работает при отрицательных ребрах.*/
  445.     pair<int, vector<int>> dijkstra(int s, int t)
  446.     {
  447.         vector<int> path;
  448.  
  449.         map<int, int> d; // расстояние до вершины от старта
  450.         map<int, int> p; // "родитель" вершины в кратчайшем пути от старта
  451.         map<int, bool> used; // непосещенность вершины
  452.  
  453.         for (map<int, vector<pair<int, int>>>::iterator it = g.g.begin(); it != g.g.end(); it++)
  454.         {
  455.             int v = (*it).first;
  456.             d[v] = INF; // изначально кратчайшего пути нет <=> расстояние равно бесконечности
  457.             p[v] = -1;
  458.             used[v] = false;
  459.         }
  460.  
  461.         d[s] = 0;
  462.         p[s] = s; // родитель старта - сама стартовая вершина
  463.         for (int i = 0; i < g.g.size(); i++)
  464.         {
  465.             int v = -1;
  466.             for (map<int, vector<pair<int, int>>>::iterator it = g.g.begin(); it != g.g.end(); it++)
  467.             {
  468.                 if (!used[(*it).first] && (v == -1 || d[(*it).first] < d[v]))
  469.                 {
  470.                     //выбирается вершина v с наименьшей величиной среди ещё не помеченных, т.е.:
  471.                     v = (*it).first;
  472.                 }
  473.             }
  474.  
  475.             if (d[v] == INF) //Если расстояние до выбранной вершины v оказывается равным бесконечности, то алгоритм останавливается
  476.             {
  477.                 break;
  478.             }
  479.  
  480.             used[v] = true;
  481.             for (int i = 0; i < g.g[v].size(); i++) //Иначе вершина помечается как помеченная, и просматриваются все рёбра, исходящие из данной вершины
  482.             {
  483.                 if (d[g.g[v][i].first] > d[v] + g.g[v][i].second) //Если релаксация успешна(т.е.расстояние d[to] меняется),
  484.                 {
  485.                     d[g.g[v][i].first] = d[v] + g.g[v][i].second; //то пересчитывается расстояние d[]
  486.                     p[g.g[v][i].first] = v;//и сохраняется предок p[].
  487.                 }
  488.             }
  489.         }
  490.  
  491.         /*if (p[t] == -1)
  492.         {
  493.         return make_pair(-1, path);
  494.         }*/
  495.         int cur = t;
  496.         while (cur != s)
  497.         {
  498.             path.push_back(cur);
  499.             cur = p[cur];
  500.         }
  501.         path.push_back(cur);
  502.  
  503.         reverse(path.begin(),
  504.             path.end()); // так как в массив путь добавлялся от конца в начало, надо его перевернуть
  505.         return make_pair(d[t], path);
  506.     }
  507.  
  508.     /*Задание 4b. Здесь под условия подходит алгоритм Флойда
  509.     http://e-maxx.ru/algo/floyd_warshall_algorithm*/
  510.  
  511.     void floyd(map<int, map<int, int>>& d, map<int, map<int, int>>& next)
  512.     {
  513.         for (map<int, vector<pair<int, int>>>::iterator it = g.g.begin(); it != g.g.end(); it++)
  514.         {
  515.             map<int, int> tmp, tmp2;
  516.             d[(*it).first] = tmp;
  517.             next[(*it).first] = tmp2;
  518.             for (map<int, vector<pair<int, int>>>::iterator it2 = g.g.begin(); it2 != g.g.end();
  519.                 it2++)
  520.             {
  521.                 d[(*it).first][(*it2).first] = INF; // сначала все вершины недостижимы
  522.                 next[(*it).first][(*it2).first] = -1;
  523.             }
  524.         }
  525.         for (map<int, vector<pair<int, int>>>::iterator it = g.g.begin(); it != g.g.end(); it++)
  526.         {
  527.             d[(*it).first][(*it).first] = 0;
  528.             for (int i = 0; i < g.g[(*it).first].size(); i++)
  529.             {
  530.                 d[(*it).first][g.g[(*it).first][i].first]
  531.                     = g.g[(*it).first][i].second; // задаем d все заданные веса ребер (d(i,j) равна весу ребра между i и j)
  532.                 next[(*it).first][g.g[(*it).first][i].first] = g.g[(*it).first][i].first;
  533.             }
  534.         }
  535.         /*Все, что мы делаем, это мы для каждой вершины i и j проверяем,
  536.         нет ли такого пути через вершину k, такой, что путь i->k->j короче,
  537.         чем текущий путь от i до j.Соответственно, все, что мы делаем,
  538.         это проходимся по всем вершинам k от 1 до n - ной и проверяем для
  539.         всех вершин i и j это условие.Если путь через k короче, чем текущая длина
  540.         пути d(i, j), то мы обновляем это d(i, j) длиной пути через k.
  541.         А next просто хранит предков для восстановления пути между i и j*/
  542.         for (map<int, vector<pair<int, int>>>::iterator k = g.g.begin(); k != g.g.end(); k++)
  543.         {
  544.             for (map<int, vector<pair<int, int>>>::iterator i = g.g.begin(); i != g.g.end(); i++)
  545.             {
  546.                 for (map<int, vector<pair<int, int>>>::iterator j = g.g.begin(); j != g.g.end();
  547.                     j++)
  548.                 {
  549.                     if (d[(*i).first][(*k).first] + d[(*k).first][(*j).first]
  550.                         < d[(*i).first][(*j).first])
  551.                     {
  552.                         d[(*i).first][(*j).first]
  553.                             = d[(*i).first][(*k).first] + d[(*k).first][(*j).first];
  554.                         next[(*i).first][(*j).first] = next[(*i).first][(*k).first];
  555.                     }
  556.                 }
  557.             }
  558.         }
  559.     }
  560.  
  561.     /* Задание 4b. Классический алгоритм Форда-Беллмана c выводом отрицательного цикла
  562.     http://e-maxx.ru/algo/ford_bellman
  563.     */
  564.     vector<int> ford_bellman(int s, map<int, int>& d)
  565.     {
  566.         d[s] = 0; // длина пути от стартовой вершины = 0
  567.         int x;
  568.         vector<int> negative_path;
  569.         map<int, int> p;
  570.         for (map<int, vector<pair<int, int>>>::iterator it = g.g.begin(); it != g.g.end(); it++)
  571.         {
  572.             p[(*it).first] = -1; // предки в путях инициализируются -1
  573.         }
  574.         p[s] = s;
  575.  
  576.         for (int k = 0; k < g.g.size(); ++k)
  577.         {
  578.             x = -1; // переменная сигнализирует о том, что найден цикл
  579.             for (map<int, vector<pair<int, int>>>::iterator it = g.g.begin(); it != g.g.end(); it++)
  580.             {
  581.                 int v = (*it).first; // проходим по всем вершинам от 0 до n - 1
  582.                 for (int j = 0; j < g.g[v].size(); j++) // проходим по соседям текущей вершины
  583.                 {
  584.                     if (d[v] < INF) // если кратчайшее расстояние от s до текущей вершины уже найдено,
  585.                     {
  586.                         if (d[g.g[v][j].first] > d[v] + g.g[v][j].second) // то проверяем неравенство беллмана
  587.                         {
  588.                             d[g.g[v][j].first] = max(-INF, d[v] + g.g[v][j].second); // если оно не выполняется, то проводим релаксацию
  589.                             p[g.g[v][j].first] = v; // родителем соседа назначаем текущую вершину
  590.                             x = g.g[v][j].first;
  591.                         }
  592.                     }
  593.                 }
  594.             }
  595.         }
  596.  
  597.         if (x != -1) // если x не равно -1, то x содержит в себе стартовую вершину цикла отрицательного веса, поэтому выводим цикл
  598.         {
  599.             int y = x;
  600.             for (int i = 0; i < g.g.size(); ++i)
  601.             {
  602.                 y = p[y]; // проходим n раз по циклу
  603.             }
  604.             for (int cur = y;; cur = p[cur]) // начинаем от вершины y - вершины, находящейся в цикле
  605.             {
  606.                 negative_path.push_back(cur);
  607.                 if (cur == y && negative_path.size() > 1) // если мы замкнули цикл (то есть cur равен вершине y, с которой мы
  608.                                                           // стартовали, то выходим из цикла
  609.                 {
  610.                     break;
  611.                 }
  612.             }
  613.  
  614.             reverse(negative_path.begin(), negative_path.end()); // реверсим массив, куда добавлялся цикл
  615.             return negative_path; // выводим непустой массив, содержащий цикл отрицательного веса
  616.         }
  617.         return negative_path; // иначе выводим пустой массив. Так как d передавалось ссылкой, так же мы получим после этого массив d
  618.                               // длин кратчайших путей от s до всех остальных вершин.
  619.     }
  620.  
  621.     /* Задание 5. Реализация алгоритма Форда-Фалкерсона с использованием dfs.
  622.  
  623.     https://neerc.ifmo.ru/wiki/index.php?title=Алгоритм_Форда-Фалкерсона,_реализация_с_помощью_поиска_в_глубину
  624.     */
  625.     // Cmin — пропускная способность в текущем подпотоке
  626.     int ford_falkerson(int v, int Cmin, map<int, map<int, int>>& flow, map<int, bool>& used)
  627.     {
  628.         if (v == g.t)
  629.         {
  630.             return Cmin;
  631.         }
  632.         used[v] = true;
  633.         for (int i = 0; i < g.g[v].size(); i++)
  634.         {
  635.             int u = g.g[v][i].first;
  636.             int cap = g.g[v][i].second;
  637.             if (!used[u] && cap > flow[v][u])
  638.             {
  639.                 int delta = ford_falkerson(u, min(Cmin, cap - flow[v][u]), flow, used);
  640.                 if (delta > 0)
  641.                 {
  642.                     //величина потока итеративно увеличивается посредством поиска увеличивающего
  643.                     //пути(путь от источника s к стоку t, вдоль которого можно послать ненулевой поток).
  644.                     flow[v][u] += delta;
  645.                     flow[u][v] -= delta;
  646.                     return delta;
  647.                 }
  648.             }
  649.         }
  650.         return 0;
  651.     }
  652. };
  653.  
  654. int main()
  655. {
  656.     string in_path = "input.txt";
  657.     string out_path = "output.txt";
  658.  
  659.     Graph g;
  660.     GraphFunctions gf;
  661.  
  662.     // вывод графа
  663.  
  664.     //g = Graph(in_path);
  665.     //g.print(out_path);
  666.  
  667.    
  668.     // 1b задание 3 вариант
  669.  
  670.     /*g = Graph("input-1b-3-a.txt");
  671.     Graph b("input-1b-3-b.txt");
  672.     gf = GraphFunctions(g);
  673.     gf.graph_union(b).print(out_path);*/
  674.  
  675.     // 2 задание 3 вариант
  676.  
  677.     /*g = Graph("input-2-3.txt");
  678.     gf = GraphFunctions(g);
  679.     int v;
  680.     cin >> v;
  681.     vector<int> result = gf.reachable_vertices(v);
  682.     for (int i = 0; i < result.size(); i++)
  683.     {
  684.     cout << result[i] << " ";
  685.     }
  686.     cout << endl;*/
  687.  
  688.     // 2 задание 15 вариант
  689.  
  690.     g = Graph("input-2-5.txt");
  691.     gf = GraphFunctions(g);
  692.     cout << gf.comp_count() << endl;
  693.  
  694.     // 3 задание ПРИМА
  695.  
  696.     /*g = Graph("input-3.txt");
  697.     gf = GraphFunctions(g);
  698.     Graph mst = gf.prim();
  699.     mst.print(out_path);*/
  700.  
  701.     // Задание 4b  4 вар
  702.  
  703.     //g = Graph("4b2.txt");
  704.     ////g = Graph("input-4b.txt");
  705.     //gf = GraphFunctions(g);
  706.     //map<int, int> d;
  707.     //for (map<int, vector<pair<int, int>>>::iterator it = g.g.begin(); it != g.g.end(); it++)
  708.     //{
  709.     //  d[(*it).first] = INF;
  710.     //}
  711.     //int u, v1, v2, n;
  712.     //cin >> u >> v1 >> v2;
  713.     //vector<int> result = gf.ford_bellman(u, d);
  714.     //if (result.size() > 0)
  715.     //{
  716.     //  cout << "Found negative cycle: ";
  717.     //  for (int i = 0; i < result.size(); i++)
  718.     //  {
  719.     //      cout << result[i] << " ";
  720.     //  }
  721.     //  cout << endl;
  722.     //}
  723.     //else
  724.     //{
  725.     //  cout << d[v1] << " " << d[v2] << endl;
  726.     //}
  727.  
  728.     // Задание 4с 7 вар
  729.  
  730.     //g = Graph("input-4c.txt");
  731.     //gf = GraphFunctions(g);
  732.     //map<int, map<int, int>> d;
  733.     ////d - это кратчайшиe расстояния между
  734.     ////любыми двумя вершинами, то есть в итоге у нас каждое d(i, j) содержит длину кратчайшего расстояния
  735.     //map<int, map<int, int>> next;
  736.     //gf.floyd(d, next);
  737.     //int v, n;
  738.     //// n - судя по всему просто рандомное число, и мы смотрим, чтобы расстояние было больше.
  739.     //cin >> v >> n;
  740.     //for (map<int, vector<pair<int, int>>>::iterator it = g.g.begin(); it != g.g.end(); it++)
  741.     //{
  742.     //  int u = (*it).first;
  743.     // 
  744.     //  if (d[v][u] == INF)//если ребра нет
  745.     //  {
  746.     //      //cout << -1 << endl;
  747.     //      continue;
  748.     //  }
  749.     //  if (d[v][u] > n)
  750.     //  {
  751.     //      cout << v << " " << u << ":" << endl;
  752.     //      cout << d[v][u] << endl;
  753.     //  }
  754.     //}
  755.  
  756.     // Задание 5
  757.  
  758.     /*int s, t;
  759.     cin >> s >> t;
  760.     g = Graph(s, t, "input-5.txt");
  761.     gf = GraphFunctions(g);
  762.     map<int, bool> used;
  763.     map<int, map<int, int>> flow;
  764.     for (map<int, vector<pair<int, int>>>::iterator it = g.g.begin(); it != g.g.end(); it++)
  765.     {
  766.         used[(*it).first] = false;
  767.         for (map<int, vector<pair<int, int>>>::iterator it2 = g.g.begin(); it2 != g.g.end(); it2++)
  768.         {
  769.             flow[(*it).first][(*it2).first] = 0;
  770.         }
  771.     }
  772.     int max_result = 0, max_flow = 0;
  773.     while ((max_result = gf.ford_falkerson(s, INF, flow, used)) > 0)
  774.     {
  775.         used = gf.empty_used();
  776.         max_flow += max_result;
  777.     }
  778.     cout << max_flow << endl;
  779.     for (map<int, map<int, int>>::iterator it = flow.begin(); it != flow.end(); it++)
  780.     {
  781.         int v = (*it).first;
  782.         for (int i = 0; i < g.g[v].size(); i++)
  783.         {
  784.             cout << v << " " << g.g[v][i].first << " " << flow[v][g.g[v][i].first] << "/"
  785.                 << g.g[v][i].second << endl;
  786.         }
  787.     }*/
  788.  
  789.     system("pause");
  790. }
Add Comment
Please, Sign In to add comment