Advertisement
dan_sml

Sem_2_Task_8

May 3rd, 2022
1,016
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.89 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <unordered_map>
  5. #include <queue>
  6.  
  7. struct Edge;
  8.  
  9. const int64_t INF = int64_t(1e15);
  10.  
  11. namespace {
  12.     using NumsVec = std::vector<int64_t>;
  13.     using VecNumsVec = std::vector<NumsVec>;
  14.     using BoolVec = std::vector<bool>;
  15.     using EdgeVec = std::vector<Edge>;
  16.     using VecEdgeVec = std::vector<EdgeVec>;
  17.     using UnMapNumEdge = std::unordered_map<int64_t, Edge>;
  18. }
  19.  
  20. struct Edge {
  21.     Edge() = default;
  22.     Edge(std::pair<size_t, size_t> edge) : from(edge.first), to(edge.second) {};
  23.     Edge(size_t i, size_t j, size_t w) : from(i), to(j), c(w) {};
  24.  
  25.     bool operator==(const Edge& other) const {
  26.         return from == other.from && to == other.to;
  27.     }
  28.  
  29.     Edge Reverse() {
  30.         return Edge(to, from, c);
  31.     }
  32.  
  33.     size_t from = 0;
  34.     size_t to = 0;
  35.     int64_t c = 0;
  36. };
  37.  
  38. std::istream& operator>>(std::istream& input, Edge& edge) {
  39.     input >> edge.from >> edge.to >> edge.c;
  40.     --edge.from;
  41.     --edge.to;
  42.     return input;
  43. }
  44.  
  45. void InputEdges(std::vector<Edge>& edges) {
  46.     for (auto& edge : edges) {
  47.         std::cin >> edge;
  48.     }
  49. }
  50.  
  51. template<>
  52. struct std::hash<Edge> {
  53.     size_t operator()(const Edge& p) const {
  54.         return p.from * p.to;
  55.     }
  56. };
  57.  
  58. std::ostream& operator<<(std::ostream& output, NumsVec& vec) {
  59.     for (auto elem : vec) {
  60.         std::cout << elem + 1 << " ";
  61.     }
  62.     return output;
  63. }
  64.  
  65. struct Graph {
  66.     Graph(size_t n) : size(n), neighbours(n), visited(n, false), color(n, 0),
  67.     top_sort(n, 0), top_sort_pos(n - 1), d(n, INF) {};
  68.  
  69.     Graph(size_t n, EdgeVec& edges) : size(n), h(n, 0), e(n, 0), flow(n, NumsVec(n, 0)), neighbours(n) {
  70.         for (auto edge : edges) {
  71.             auto& edge_direct = neighbours[edge.from][edge.to];
  72.             edge_direct.from = edge.from;
  73.             edge_direct.to = edge.to;
  74.             edge_direct.c += edge.c;
  75.             auto& edge_back = neighbours[edge.to][edge.from];
  76.             edge_back.to = edge.from;
  77.             edge_back.from = edge.to;
  78.         }
  79.     };
  80.  
  81.     size_t size = 0;
  82.     bool cycle = false;
  83.  
  84.     std::vector<UnMapNumEdge> neighbours;
  85.     VecNumsVec matrix;
  86.     VecNumsVec flow;
  87.     BoolVec visited;
  88.     NumsVec color;
  89.     NumsVec top_sort;
  90.     NumsVec d;
  91.     NumsVec e;
  92.     NumsVec h;
  93.     EdgeVec route;
  94.     size_t max_flow = 0;
  95.     size_t sum_w = 0;
  96.     size_t top_sort_pos = 0;
  97. };
  98.  
  99. void Push(Graph& g, size_t u, Edge edge) {
  100.     size_t v = edge.to;
  101.     int64_t flow = std::min(g.e[u], edge.c - g.flow[u][v]);
  102.     g.flow[u][v] += flow;
  103.     g.flow[v][u] = -g.flow[u][v];
  104.     g.e[u] -= flow;
  105.     g.e[v] += flow;
  106. }
  107.  
  108. void Lift(Graph& g, size_t u) {
  109.     g.h[u] = INF;
  110.     for (auto [v, edge] : g.neighbours[u]) {
  111.         if (edge.c - g.flow[u][v] > 0) {
  112.             g.h[u] = std::min(g.h[u], g.h[v] + 1);
  113.         }
  114.     }
  115. }
  116.  
  117. void ChangeFlow(Graph& g, size_t u) {
  118.     for (auto [v, edge] : g.neighbours[u]) {
  119.         if (edge.c - g.flow[u][v] > 0 && g.h[u] == g.h[v] + 1) {
  120.             Push(g, u, edge);
  121.             return;
  122.         }
  123.     }
  124.     Lift(g, u);
  125. }
  126.  
  127. size_t FindOverflowing(Graph& g, size_t s, size_t t) {
  128.     for (size_t v = 0; v < g.size; ++v) {
  129.         if (v != s && v != t && g.e[v] > 0) {
  130.             return v;
  131.         }
  132.     }
  133.     return t;
  134. }
  135.  
  136. void GenericPreflowPush(Graph& g, size_t s, size_t t) {
  137.     g.h[s] = g.size;
  138.     for (auto [v, edge] : g.neighbours[s]) {
  139.         g.e[v] += edge.c;
  140.         g.flow[s][v] = edge.c;
  141.         g.flow[v][s] = -edge.c;
  142.     }
  143.     size_t u;
  144.     while ((u = FindOverflowing(g, s, t)) != t) {
  145.         ChangeFlow(g, u);
  146.     }
  147.     for (auto [v, edge] : g.neighbours[s]) {
  148.         g.max_flow += g.flow[s][v];
  149.     }
  150. }
  151.  
  152. int main() {
  153.     size_t n, m;
  154.     std::cin >> n >> m;
  155.     EdgeVec edges(m);
  156.     InputEdges(edges);
  157.     Graph g(n, edges);
  158.     GenericPreflowPush(g, 0, n - 1);
  159.     std::cout << g.max_flow;
  160. }
  161.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement