Advertisement
mfgnik

Untitled

Apr 3rd, 2020
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.24 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <numeric>
  4. #include <queue>
  5. #include <unordered_map>
  6. #include <utility>
  7. #include <vector>
  8.  
  9.  
  10. const int64_t kInfinity = 2000000000;
  11.  
  12.  
  13. struct Edge {
  14.     int64_t vertex, capacity, flow, next;
  15.     Edge() {}
  16.     Edge(int64_t vertex, int64_t cap, int64_t flow, int64_t next)
  17.         : vertex(vertex), capacity(cap), flow(flow), next(next) {}
  18. };
  19.  
  20. class Graph {
  21. public:
  22.     explicit Graph(int vertices, int edge_count) : vertices_(vertices), edge_count_(0),
  23.                                                    edges_(2 * edge_count) {}
  24.  
  25.     void Reset(int source, int sink) {
  26.         source_ = source;
  27.         sink_ = sink;
  28.         head_.assign(vertices_, -1);
  29.     }
  30.  
  31.     void AddEdge(int first_vertex, int second_vertex, int64_t cap, int64_t right_capacity) {
  32.         edges_[edge_count_] = Edge(second_vertex, cap, 0, head_[first_vertex]);
  33.         head_[first_vertex] = edge_count_;
  34.         edges_[edge_count_ + 1] = Edge(first_vertex, right_capacity, 0,
  35.                                        head_[second_vertex]);
  36.         head_[second_vertex] = edge_count_ + 1;
  37.         edge_count_ += 2;
  38.     }
  39.  
  40.     int64_t MaxFlow() {
  41.         int64_t max_flow = 0;
  42.         while (BFS()) {
  43.             current_ = head_;
  44.             int64_t delta = DFS(source_, kInfinity);
  45.             while (delta) {
  46.                 max_flow += delta;
  47.                 delta = DFS(source_, kInfinity);
  48.             }
  49.         }
  50.         return max_flow;
  51.     }
  52.  
  53.     bool BFS() {
  54.         distances_.assign(vertices_, -1);
  55.         std::queue<int> queue;
  56.         queue.push(source_);
  57.         distances_[source_] = 0;
  58.         while (!queue.empty()) {
  59.             int top = queue.front();
  60.             queue.pop();
  61.             for (int index = head_[top]; index != -1; index = edges_[index].next) {
  62.                 if (edges_[index].flow < edges_[index].capacity &&
  63.                     distances_[edges_[index].vertex] == -1) {
  64.                     distances_[edges_[index].vertex] = distances_[top] + 1;
  65.                     queue.push(edges_[index].vertex);
  66.                 }
  67.             }
  68.         }
  69.         return distances_[sink_] != -1;
  70.     }
  71.  
  72.     int64_t DFS(int vertex, int64_t flow) {
  73.         if (vertex == sink_) {
  74.             return flow;
  75.         }
  76.         for (int index = current_[vertex]; index >= 0; index = edges_[index].next) {
  77.             if (edges_[index].flow < edges_[index].capacity &&
  78.                 distances_[vertex] + 1 == distances_[edges_[index].vertex]) {
  79.                 int min_flow = DFS(edges_[index].vertex,
  80.                                    std::min(flow, edges_[index].capacity - edges_[index].flow));
  81.                 if (min_flow > 0) {
  82.                     edges_[index].flow += min_flow;
  83.                     edges_[index ^ 1].flow -= min_flow;
  84.                     return min_flow;
  85.                 }
  86.             }
  87.         }
  88.         return 0;
  89.     }
  90.  
  91. private:
  92.     int vertices_;
  93.     int edge_count_;
  94.     int source_;
  95.     int sink_;
  96.     std::vector<Edge> edges_;
  97.     std::vector<int> head_;
  98.     std::vector<int> distances_;
  99.     std::vector<int> current_;
  100. };
  101.  
  102.  
  103. namespace std {
  104.     template<>
  105.     struct hash<std::pair<int, int>> {
  106.         inline size_t operator()(const std::pair<int, int> &v) const {
  107.             std::hash<int> int_hasher;
  108.             return int_hasher(v.first) ^ int_hasher(v.second);
  109.         }
  110.     };
  111. }// namespace std
  112.  
  113.  
  114. int main() {
  115.     int vertices_count, edges_count;
  116.     std::cin >> vertices_count >> edges_count;
  117.     std::vector<int> weights;
  118.     for (int index = 0; index < vertices_count; ++index) {
  119.         int current_weight;
  120.         std::cin >> current_weight;
  121.         weights.push_back(current_weight);
  122.     }
  123.     std::unordered_map<std::pair<int, int>, std::pair<int, int>> edges;
  124.     for (int index = 0; index < edges_count; ++index) {
  125.         int first_vertex, second_vertex;
  126.         std::cin >> first_vertex >> second_vertex;
  127.         if (first_vertex < second_vertex) {
  128.             edges[std::make_pair(first_vertex, second_vertex)].first = kInfinity;
  129.         } else {
  130.             edges[std::make_pair(second_vertex, first_vertex)].second = kInfinity;
  131.         }
  132.     }
  133.     Graph base_graph(vertices_count + 2, 2 * vertices_count +
  134.                                                  static_cast<int>(edges.size()));
  135.     base_graph.Reset(0, vertices_count + 1);
  136.     for (auto &edge : edges) {
  137.         base_graph.AddEdge(edge.first.first, edge.first.second,
  138.                            edge.second.first, edge.second.second);
  139.     }
  140.  
  141.     for (int index = 0; index < static_cast<int>(weights.size()); ++index) {
  142.         base_graph.AddEdge(0, index + 1, weights[index], 0);
  143.     }
  144.     int left = 0;
  145.     int right = *std::max_element(weights.begin(), weights.end());
  146.     int64_t weights_sum = std::accumulate(weights.begin(), weights.end(), 0);
  147.     while (right - left > 1) {
  148.         auto middle = (left + right) / 2;
  149.         Graph graph = base_graph;
  150.         for (int index = 0; index < vertices_count; ++index) {
  151.             graph.AddEdge(index + 1, vertices_count + 1, middle, 0);
  152.         }
  153.         if (graph.MaxFlow() == weights_sum) {
  154.             right = middle;
  155.         } else {
  156.             left = middle;
  157.         }
  158.     }
  159.     std::cout << right;
  160. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement