ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Dinic
    232's competitive-programming templates. 2024. 10. 22. 14:16
    template <typename T>
    struct Dinic {
      struct Edge {
        int to;
        T cap;
    
        Edge(int to, T cap) : to(to), cap(cap) {
          void(0);
        }
      };
    
      int n;
      int s;
      int t;
      std::vector<int> lvl;
      std::vector<int> ptr;
      std::vector<Edge> edges;
      std::vector<std::vector<int>> g;
    
      Dinic(int n, int s, int t) : n(n), s(s), t(t), lvl(n), ptr(n), g(n) {
        assert(0 <= s && s < n);
        assert(0 <= t && t < n);
        assert(s != t);
      }
    
      void addEdge(int u, int v, T c, bool bidirectional = false) {
        g[u].push_back(edges.size());
        edges.emplace_back(v, c);
        g[v].push_back(edges.size());
        edges.emplace_back(u, bidirectional ? c : 0);
      }
    
      void initLevel() {
        std::fill(lvl.begin(), lvl.end(), -1);
        lvl[s] = 0;
        std::vector<int> que(1, s);
        for (int b = 0; b < int(que.size()); ++b) {
          for (int eid : g[que[b]]) {
            auto [to, cap] = edges[eid];
            if (cap > 0 && lvl[to] == -1) {
              lvl[to] = lvl[que[b]] + 1;
              que.push_back(to);
            }
          }
        }
      }
    
      T augment(int u, T lim) {
        if (u == t) {
          return lim;
        }
        for (int& i = ptr[u]; i < int(g[u].size()); ++i) {
          auto& e = edges[g[u][i]];
          if (e.cap > 0 && lvl[e.to] == lvl[u] + 1) {
            T flow = augment(e.to, std::min(lim, e.cap));
            if (flow > 0) {
              e.cap -= flow;
              edges[g[u][i] ^ 1].cap += flow;
              return flow;
            }
          }
        }
        return 0;
      }
    
      T work() {
        T res = 0;
        while (true) {
          initLevel();
          if (lvl[t] == -1) {
            break;
          }
          std::fill(ptr.begin(), ptr.end(), 0);
          while (true) {
            T flow = augment(s, std::numeric_limits<T>::max());
            if (flow == 0) {
              break;
            }
            res += flow;
          }
        }
        return res;
      }
    
      [[nodiscard]] std::vector<bool> getMinCut() const {
        std::vector<bool> res(n);
        for (int i = 0; i < n; ++i) {
          res[i] = (lvl[i] != -1);
        }
        return res;
      }
    };

    '232's competitive-programming templates.' 카테고리의 다른 글

    MinCostMaxFlow  (2) 2024.10.22
    (useless) BipartiteMatching (slow)  (0) 2024.10.22
    MinMaxPQ  (1) 2024.10.03
    Centroid, CentroidTree  (0) 2024.09.26
    polynomial  (0) 2024.09.21
Designed by Tistory.