Problem p02562 (C++)

Buggy submission (status: Runtime Error):
#pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>
// #include<ext/pb_ds/tag_and_trait.hpp>
// using namespace __gnu_pbds;
// #include<boost/multiprecision/cpp_int.hpp>
// namespace multiprecisioninteger = boost::multiprecision;
// using cint=multiprecisioninteger::cpp_int;
using namespace std;
using ll = long long;
#define double long double
using datas = pair<ll, ll>;
using ddatas = pair<double, double>;
using tdata = pair<ll, datas>;
using vec = vector<ll>;
using mat = vector<vec>;
using pvec = vector<datas>;
using pmat = vector<pvec>;
// using
// llset=tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;
#define For(i, a, b) for (i = a; i < (ll)b; ++i)
#define bFor(i, b, a) for (i = b, --i; i >= (ll)a; --i)
#define rep(i, N) For(i, 0, N)
#define rep1(i, N) For(i, 1, N)
#define brep(i, N) bFor(i, N, 0)
#define brep1(i, N) bFor(i, N, 1)
#define all(v) (v).begin(), (v).end()
#define allr(v) (v).rbegin(), (v).rend()
#define vsort(v) sort(all(v))
#define vrsort(v) sort(allr(v))
#define endl "\n"
#define eb emplace_back
#define print(v) cout << v << endl
#define printyes cout << "Yes" << endl
#define printno cout << "No" << endl
#define printYES cout << "YES" << endl
#define printNO cout << "NO" << endl
#define output(v)                                                              \
  do {                                                                         \
    bool f = 0;                                                                \
    for (auto outi : v) {                                                      \
      cout << (f ? " " : "") << outi;                                          \
      f = 1;                                                                   \
    }                                                                          \
    cout << endl;                                                              \
  } while (0)
#define matoutput(v)                                                           \
  do {                                                                         \
    for (auto outimat : v)                                                     \
      output(outimat);                                                         \
  } while (0)
const ll mod = 1000000007;
// const ll mod=998244353;
const ll inf = 1LL << 60;
const double PI = acos(-1);
const double eps = 1e-9;
template <class T> inline bool chmax(T &a, T b) {
  bool x = a < b;
  if (x)
    a = b;
  return x;
}
template <class T> inline bool chmin(T &a, T b) {
  bool x = a > b;
  if (x)
    a = b;
  return x;
}

void startupcpp() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(15);
}
template <class Cap, class Cost> struct mcf_graph {
public:
  mcf_graph() {}
  mcf_graph(int n) : _n(n), g(n) {}

  int add_edge(int from, int to, Cap cap, Cost cost) {
    assert(0 <= from && from < _n);
    assert(0 <= to && to < _n);
    int m = int(pos.size());
    pos.push_back({from, int(g[from].size())});
    int from_id = int(g[from].size());
    int to_id = int(g[to].size()) + int(from == to);
    g[from].push_back(_edge{to, to_id, cap, cost});
    g[to].push_back(_edge{from, from_id, 0, -cost});
    return m;
  }

  struct edge {
    int from, to;
    Cap cap, flow;
    Cost cost;
  };

  edge get_edge(int i) {
    assert(0 <= i && i < int(pos.size()));
    auto _e = g[pos[i].first][pos[i].second];
    auto _re = g[_e.to][_e.rev];
    return edge{
        pos[i].first, _e.to, _e.cap + _re.cap, _re.cap, _e.cost,
    };
  }
  vector<edge> edges() {
    int m = int(pos.size());
    vector<edge> result(m);
    for (int i = 0; i < m; ++i) {
      result[i] = get_edge(i);
    }
    return result;
  }

  pair<Cap, Cost> flow(int s, int t) {
    return flow(s, t, numeric_limits<Cap>::max());
  }
  pair<Cap, Cost> flow(int s, int t, Cap flow_limit) {
    return slope(s, t, flow_limit).back();
  }
  vector<pair<Cap, Cost>> slope(int s, int t) {
    return slope(s, t, numeric_limits<Cap>::max());
  }
  vector<pair<Cap, Cost>> slope(int s, int t, Cap flow_limit) {
    assert(0 <= s && s < _n);
    assert(0 <= t && t < _n);
    assert(s != t);
    // variants(C=maxcost):
    //-(n-1)C<=dual[s]<=dual[i]<=dual[t]=0
    // reduced cost(=e.cost+dual[e.from]-dual[e.to])>=0 for all edge
    vector<Cost> dual(_n, 0), dist(_n);
    vector<int> pv(_n), pe(_n);
    vector<bool> vis(_n);
    auto dual_ref = [&]() {
      fill(dist.begin(), dist.end(), numeric_limits<Cost>::max());
      fill(pv.begin(), pv.end(), -1);
      fill(pe.begin(), pe.end(), -1);
      fill(vis.begin(), vis.end(), false);
      struct Q {
        Cost key;
        int to;
        bool operator<(Q r) const { return key > r.key; }
      };
      priority_queue<Q> que;
      dist[s] = 0;
      que.push(Q{0, s});
      while (!que.empty()) {
        int v = que.top().to;
        que.pop();
        if (vis[v])
          continue;
        vis[v] = true;
        if (v == t)
          break;
        // dist[v]=shortest(s,v)+dual[s]-dual[v]
        // dist[v]>=0(all reduced cost are positive)
        // dist[v]<=(n-1)C
        for (int i = 0; i < int(g[v].size()); ++i) {
          auto e = g[v][i];
          if (vis[e.to] || !e.cap)
            continue;
          // |-dual[e.to]+dual[v]|<=(n-1)C
          // cost<=C--(n-1)C+0=nC
          Cost cost = e.cost - dual[e.to] + dual[v];
          if (dist[e.to] - dist[v] > cost) {
            dist[e.to] = dist[v] + cost;
            pv[e.to] = v;
            pe[e.to] = i;
            que.push(Q{dist[e.to], e.to});
          }
        }
      }
      if (!vis[t])
        return false;

      for (int v = 0; v < _n; ++v) {
        if (!vis[v])
          continue;
        // dual[v]=dual[v]-dist[t]+dist[v]
        //    =dual[v]-(shortest(s,t)+dual[s]-dual[t])+(shortest(s,v)+dual[s]-dual[v])
        //    =-shortest(s,t)+dual[t]+shortest(s,v)
        //    =shortest(s,v)-shortest(s,t)>=0-(n-1)C
        dual[v] -= dist[t] - dist[v];
      }
      return true;
    };
    Cap flow = 0;
    Cost cost = 0, prev_cost_per_flow = -1;
    vector<pair<Cap, Cost>> result;
    result.push_back({flow, cost});
    while (flow < flow_limit) {
      if (!dual_ref())
        break;
      Cap c = flow_limit - flow;
      for (int v = t; v != s; v = pv[v]) {
        c = min(c, g[pv[v]][pe[v]].cap);
      }
      for (int v = t; v != s; v = pv[v]) {
        auto &e = g[pv[v]][pe[v]];
        e.cap -= c;
        g[v][e.rev].cap += c;
      }
      Cost d = -dual[s];
      flow += c;
      cost += c * d;
      if (prev_cost_per_flow == d) {
        result.pop_back();
      }
      result.push_back({flow, cost});
      prev_cost_per_flow = d;
    }
    return result;
  }

private:
  int _n;

  struct _edge {
    int to, rev;
    Cap cap;
    Cost cost;
  };

  vector<pair<int, int>> pos;
  vector<vector<_edge>> g;
};
int main() {
  startupcpp();
  int i, j, N, K;
  cin >> N >> K;
  mat g(N, vec(N));
  vector<string> ans(N);
  vec pot(N + 1, 0);
  rep(i, N) rep(j, N) {
    cin >> g[i][j];
    chmax(pot[j], g[i][j]);
    ans[i] += '.';
  }
  rep(i, N) chmax(pot[N + 1], pot[i]);
  mcf_graph<int, ll> flow(N * 2 + 2);
  rep(i, N) {
    rep(j, N) { flow.add_edge(i, j + N, 1, pot[j] - g[i][j]); }
    flow.add_edge(N << 1, i, K, 0);
    flow.add_edge(i + N, N << 1 | 1, K, pot[N + 1] - pot[i]);
  }
  auto v = flow.slope(N << 1, N << 1 | 1);
  int M = v.size();
  rep1(i, M) {
    if ((v[i].first - v[i - 1].first) * pot[N + 1] <
        (v[i].second - v[i - 1].second))
      break;
  }
  int flowlim = v[--i].first;
  print(pot[N + 1] * flowlim - v[i].second);
  mcf_graph<int, ll> flows(N * 2 + 2);
  rep(i, N) {
    rep(j, N) { flows.add_edge(i, j + N, 1, pot[j] - g[i][j]); }
    flows.add_edge(N << 1, i, K, 0);
    flows.add_edge(i + N, N << 1 | 1, K, pot[N + 1] - pot[i]);
  }
  flows.slope(N << 1, N << 1 | 1, flowlim);
  auto x = flows.edges();
  for (auto edge : x) {
    if (!edge.flow || max(edge.from, edge.to) >= N * 2)
      continue;
    ans[edge.from][edge.to - N] = 'X';
  }
  for (auto p : ans)
    print(p);
}

Fixed submission:
#pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>
// #include<ext/pb_ds/tag_and_trait.hpp>
// using namespace __gnu_pbds;
// #include<boost/multiprecision/cpp_int.hpp>
// namespace multiprecisioninteger = boost::multiprecision;
// using cint=multiprecisioninteger::cpp_int;
using namespace std;
using ll = long long;
#define double long double
using datas = pair<ll, ll>;
using ddatas = pair<double, double>;
using tdata = pair<ll, datas>;
using vec = vector<ll>;
using mat = vector<vec>;
using pvec = vector<datas>;
using pmat = vector<pvec>;
// using
// llset=tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;
#define For(i, a, b) for (i = a; i < (ll)b; ++i)
#define bFor(i, b, a) for (i = b, --i; i >= (ll)a; --i)
#define rep(i, N) For(i, 0, N)
#define rep1(i, N) For(i, 1, N)
#define brep(i, N) bFor(i, N, 0)
#define brep1(i, N) bFor(i, N, 1)
#define all(v) (v).begin(), (v).end()
#define allr(v) (v).rbegin(), (v).rend()
#define vsort(v) sort(all(v))
#define vrsort(v) sort(allr(v))
#define endl "\n"
#define eb emplace_back
#define print(v) cout << v << endl
#define printyes cout << "Yes" << endl
#define printno cout << "No" << endl
#define printYES cout << "YES" << endl
#define printNO cout << "NO" << endl
#define output(v)                                                              \
  do {                                                                         \
    bool f = 0;                                                                \
    for (auto outi : v) {                                                      \
      cout << (f ? " " : "") << outi;                                          \
      f = 1;                                                                   \
    }                                                                          \
    cout << endl;                                                              \
  } while (0)
#define matoutput(v)                                                           \
  do {                                                                         \
    for (auto outimat : v)                                                     \
      output(outimat);                                                         \
  } while (0)
const ll mod = 1000000007;
// const ll mod=998244353;
const ll inf = 1LL << 60;
const double PI = acos(-1);
const double eps = 1e-9;
template <class T> inline bool chmax(T &a, T b) {
  bool x = a < b;
  if (x)
    a = b;
  return x;
}
template <class T> inline bool chmin(T &a, T b) {
  bool x = a > b;
  if (x)
    a = b;
  return x;
}

void startupcpp() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(15);
}
template <class Cap, class Cost> struct mcf_graph {
public:
  mcf_graph() {}
  mcf_graph(int n) : _n(n), g(n) {}

  int add_edge(int from, int to, Cap cap, Cost cost) {
    assert(0 <= from && from < _n);
    assert(0 <= to && to < _n);
    int m = int(pos.size());
    pos.push_back({from, int(g[from].size())});
    int from_id = int(g[from].size());
    int to_id = int(g[to].size()) + int(from == to);
    g[from].push_back(_edge{to, to_id, cap, cost});
    g[to].push_back(_edge{from, from_id, 0, -cost});
    return m;
  }

  struct edge {
    int from, to;
    Cap cap, flow;
    Cost cost;
  };

  edge get_edge(int i) {
    assert(0 <= i && i < int(pos.size()));
    auto _e = g[pos[i].first][pos[i].second];
    auto _re = g[_e.to][_e.rev];
    return edge{
        pos[i].first, _e.to, _e.cap + _re.cap, _re.cap, _e.cost,
    };
  }
  vector<edge> edges() {
    int m = int(pos.size());
    vector<edge> result(m);
    for (int i = 0; i < m; ++i) {
      result[i] = get_edge(i);
    }
    return result;
  }

  pair<Cap, Cost> flow(int s, int t) {
    return flow(s, t, numeric_limits<Cap>::max());
  }
  pair<Cap, Cost> flow(int s, int t, Cap flow_limit) {
    return slope(s, t, flow_limit).back();
  }
  vector<pair<Cap, Cost>> slope(int s, int t) {
    return slope(s, t, numeric_limits<Cap>::max());
  }
  vector<pair<Cap, Cost>> slope(int s, int t, Cap flow_limit) {
    assert(0 <= s && s < _n);
    assert(0 <= t && t < _n);
    assert(s != t);
    // variants(C=maxcost):
    //-(n-1)C<=dual[s]<=dual[i]<=dual[t]=0
    // reduced cost(=e.cost+dual[e.from]-dual[e.to])>=0 for all edge
    vector<Cost> dual(_n, 0), dist(_n);
    vector<int> pv(_n), pe(_n);
    vector<bool> vis(_n);
    auto dual_ref = [&]() {
      fill(dist.begin(), dist.end(), numeric_limits<Cost>::max());
      fill(pv.begin(), pv.end(), -1);
      fill(pe.begin(), pe.end(), -1);
      fill(vis.begin(), vis.end(), false);
      struct Q {
        Cost key;
        int to;
        bool operator<(Q r) const { return key > r.key; }
      };
      priority_queue<Q> que;
      dist[s] = 0;
      que.push(Q{0, s});
      while (!que.empty()) {
        int v = que.top().to;
        que.pop();
        if (vis[v])
          continue;
        vis[v] = true;
        if (v == t)
          break;
        // dist[v]=shortest(s,v)+dual[s]-dual[v]
        // dist[v]>=0(all reduced cost are positive)
        // dist[v]<=(n-1)C
        for (int i = 0; i < int(g[v].size()); ++i) {
          auto e = g[v][i];
          if (vis[e.to] || !e.cap)
            continue;
          // |-dual[e.to]+dual[v]|<=(n-1)C
          // cost<=C--(n-1)C+0=nC
          Cost cost = e.cost - dual[e.to] + dual[v];
          if (dist[e.to] - dist[v] > cost) {
            dist[e.to] = dist[v] + cost;
            pv[e.to] = v;
            pe[e.to] = i;
            que.push(Q{dist[e.to], e.to});
          }
        }
      }
      if (!vis[t])
        return false;

      for (int v = 0; v < _n; ++v) {
        if (!vis[v])
          continue;
        // dual[v]=dual[v]-dist[t]+dist[v]
        //    =dual[v]-(shortest(s,t)+dual[s]-dual[t])+(shortest(s,v)+dual[s]-dual[v])
        //    =-shortest(s,t)+dual[t]+shortest(s,v)
        //    =shortest(s,v)-shortest(s,t)>=0-(n-1)C
        dual[v] -= dist[t] - dist[v];
      }
      return true;
    };
    Cap flow = 0;
    Cost cost = 0, prev_cost_per_flow = -1;
    vector<pair<Cap, Cost>> result;
    result.push_back({flow, cost});
    while (flow < flow_limit) {
      if (!dual_ref())
        break;
      Cap c = flow_limit - flow;
      for (int v = t; v != s; v = pv[v]) {
        c = min(c, g[pv[v]][pe[v]].cap);
      }
      for (int v = t; v != s; v = pv[v]) {
        auto &e = g[pv[v]][pe[v]];
        e.cap -= c;
        g[v][e.rev].cap += c;
      }
      Cost d = -dual[s];
      flow += c;
      cost += c * d;
      if (prev_cost_per_flow == d) {
        result.pop_back();
      }
      result.push_back({flow, cost});
      prev_cost_per_flow = d;
    }
    return result;
  }

private:
  int _n;

  struct _edge {
    int to, rev;
    Cap cap;
    Cost cost;
  };

  vector<pair<int, int>> pos;
  vector<vector<_edge>> g;
};
int main() {
  startupcpp();
  int i, j, N, K;
  cin >> N >> K;
  mat g(N, vec(N));
  vector<string> ans(N);
  vec pot(N + 2, 0);
  rep(i, N) rep(j, N) {
    cin >> g[i][j];
    chmax(pot[j], g[i][j]);
    ans[i] += '.';
  }
  rep(i, N) chmax(pot[N + 1], pot[i]);
  mcf_graph<int, ll> flow(N * 2 + 2);
  rep(i, N) {
    rep(j, N) { flow.add_edge(i, j + N, 1, pot[j] - g[i][j]); }
    flow.add_edge(N << 1, i, K, 0);
    flow.add_edge(i + N, N << 1 | 1, K, pot[N + 1] - pot[i]);
  }
  auto v = flow.slope(N << 1, N << 1 | 1);
  int M = v.size();
  rep1(i, M) {
    if ((v[i].first - v[i - 1].first) * pot[N + 1] <
        (v[i].second - v[i - 1].second))
      break;
  }
  int flowlim = v[--i].first;
  print(pot[N + 1] * flowlim - v[i].second);
  mcf_graph<int, ll> flows(N * 2 + 2);
  rep(i, N) {
    rep(j, N) { flows.add_edge(i, j + N, 1, pot[j] - g[i][j]); }
    flows.add_edge(N << 1, i, K, 0);
    flows.add_edge(i + N, N << 1 | 1, K, pot[N + 1] - pot[i]);
  }
  flows.slope(N << 1, N << 1 | 1, flowlim);
  auto x = flows.edges();
  for (auto edge : x) {
    if (!edge.flow || max(edge.from, edge.to) >= N * 2)
      continue;
    ans[edge.from][edge.to - N] = 'X';
  }
  for (auto p : ans)
    print(p);
}