Advertisement
Argent007

Maximal Flow (MPmag) 2023

Apr 26th, 2023
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.41 KB | None | 0 0
  1. // ConsoleApplication1.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
  2. //
  3.  
  4. #include <iostream>
  5. #include <vector>
  6. #include <queue>
  7. #include <fstream>
  8.  
  9. using std::vector;
  10. struct edge
  11. {
  12.     int beg, end;
  13.     double c, f;
  14. };
  15. using wgraph = vector<vector<edge>>;
  16. using edge_graph = vector<vector<std::pair<int, bool>>>;
  17.  
  18. wgraph get_wgraph_from_stream(std::istream& inp)
  19. {
  20.     int n;
  21.     inp >> n;
  22.     wgraph g(n);
  23.     int beg, end;
  24.     double c;
  25.     while (inp >> beg >> end >> c)
  26.     {
  27.         g[beg].push_back({beg,end,c,0.0});
  28.     }
  29.     return g;
  30. }
  31.  
  32. bool search_and_icrease_with_augment_path(const edge_graph& eg, vector<edge> &edges, int s, int t)
  33. {
  34.     int n = eg.size();
  35.     vector<double> h(n,0);
  36.     vector<int> p(n, -1);
  37.     std::queue<int> Q;
  38.     h[s] = DBL_MAX;
  39.     Q.push(s);
  40.     while (Q.size())
  41.     {
  42.         int u = Q.front();
  43.         Q.pop();
  44.         for (auto [en, out_edge] : eg[u])
  45.         {
  46.             if (out_edge && h[edges[en].end] == 0 && edges[en].c - edges[en].f > 0)
  47.             {
  48.                 h[edges[en].end] = std::min(edges[en].c - edges[en].f,h[u]);
  49.                 p[edges[en].end] = en;
  50.                 Q.push(edges[en].end);
  51.             }
  52.             else if (!out_edge && h[edges[en].beg] == 0 && edges[en].f > 0)
  53.             {
  54.                 h[edges[en].beg] = std::min(edges[en].f, h[u]);
  55.                 p[edges[en].beg] = en;
  56.                 Q.push(edges[en].beg);
  57.             }
  58.         }
  59.         if (h[t] > 0) break;
  60.     }
  61.     if (h[t] == 0) return false;
  62.     int current_edge = p[t], current_vertex=t;
  63.     while (current_edge >= 0)
  64.     {
  65.         if (current_vertex == edges[current_edge].end)
  66.         {
  67.             edges[current_edge].f += h[t];
  68.             current_vertex = edges[current_edge].beg;
  69.         }
  70.         else
  71.         {
  72.             edges[current_edge].f -= h[t];
  73.             current_vertex = edges[current_edge].end;
  74.         }
  75.         current_edge = p[current_vertex];
  76.     }
  77.     return true;
  78. }
  79.  
  80. vector<edge> maximal_flow(const wgraph& g, int s, int t)
  81. {
  82.     vector<edge> edges;
  83.    
  84.     edge_graph eg(g.size());
  85.     //edge_graph[i] содержит список рёбер, инцидентных вершине i, а также признак исходящего ребра
  86.     for (size_t u = 0; u < g.size(); u++)
  87.     {
  88.         for (auto [beg, end, c, f] : g[u])
  89.         {
  90.             edges.push_back({ beg,end,c,f });
  91.             eg[beg].push_back({ edges.size() - 1, true });
  92.             eg[end].push_back({ edges.size() - 1, false });
  93.         }
  94.     }
  95.     while (search_and_icrease_with_augment_path(eg, edges, s, t)) { std::cout << '+'; }
  96.     return edges;
  97. }
  98.  
  99. int main()
  100. {
  101.     std::fstream inp("wgraph.txt");
  102.     auto wg = get_wgraph_from_stream(inp);
  103.     auto edges = maximal_flow(wg, 0, 3);
  104.     for (auto e : edges)
  105.     {
  106.         std::cout << e.beg << " " << e.end << " " << e.c << " " << e.f << std::endl;
  107.     }
  108.     std::cout << "Hello World!\n";
  109. }
  110.  
  111. // Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки"
  112. // Отладка программы: F5 или меню "Отладка" > "Запустить отладку"
  113.  
  114. // Советы по началу работы
  115. //   1. В окне обозревателя решений можно добавлять файлы и управлять ими.
  116. //   2. В окне Team Explorer можно подключиться к системе управления версиями.
  117. //   3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения.
  118. //   4. В окне "Список ошибок" можно просматривать ошибки.
  119. //   5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода.
  120. //   6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл.
  121.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement