Problem p02542 (C++) — buggy submission, verdict: Runtime Error

/*
 * Author: Kewth

 * Date:
  echo -n '  ' && date +%Y.%m.%d # Type "!!sh" in Vim.

 * Solution:
  To be updated after "Accept".

 * Digression:

 * CopyRight:
   __  __                  __   __
  |  |/  |.-----.--.--.--.|  |_|  |--.
  |     < |  -__|  |  |  ||   _|     |
  |__|\\__||_____|________||____|__|__|

 */

#include <algorithm>
#include <cstdio>
#include <queue>
#define debug(...) fprintf(stderr, __VA_ARGS__)

typedef long long ll;

static struct {
  inline operator int() {
    int x;
    return scanf("%d", &x), x;
  }
  inline operator ll() {
    ll x;
    return scanf("%lld", &x), x;
  }
  template <class T> inline void operator()(T &x) { x = *this; }
  template <class T, class... A> inline void operator()(T &x, A &...a) {
    x = *this;
    this->operator()(a...);
  }
} read;

const int Maxn = 55;
char str[Maxn][Maxn];
int id1[Maxn][Maxn], id2[Maxn][Maxn], ip;
bool mvis[Maxn][Maxn];

const int maxn = 2605, maxm = 252605;
int head[maxn], nxt[maxm << 1], to[maxm << 1], cap[maxm << 1], cost[maxm << 1],
    hp = 1;

inline void add(int u, int v, int ca, int co) {
  if ((hp & 1) and !ca)
    return;
  nxt[++hp] = head[u];
  head[u] = hp;
  to[hp] = v;
  cap[hp] = ca;
  cost[hp] = co;
  if (!(hp & 1))
    add(v, u, 0, -co);
}

ll dis[maxn];
bool inq[maxn], vis[maxn];
int from[maxn];
bool spfa(int s, int t) {
  std::queue<int> q;
  std::fill(dis, dis + t + 1, 1000000000000000000);
  std::fill(inq, inq + t + 1, 0);
  dis[s] = 0;
  q.push(s);
  while (!q.empty()) {
    int u = q.front();
    vis[u] = 1;
    q.pop();
    inq[u] = 0;
    for (int i = head[u]; i; i = nxt[i])
      if (cap[i] and dis[u] + cost[i] < dis[to[i]]) {
        dis[to[i]] = dis[u] + cost[i];
        from[to[i]] = i ^ 1;
        if (!inq[to[i]]) {
          q.push(to[i]);
          inq[to[i]] = 1;
        }
      }
  }
  return dis[t] < 1000000000000000000;
}

ll mincostmaxflow(int s, int t) {
  ll res = 0;
  while (spfa(s, t)) {
    int flow = cap[from[t] ^ 1];
    ll sum = cost[from[t] ^ 1];
    for (int u = to[from[t]]; u != s; u = to[from[u]]) {
      flow = std::min(flow, cap[from[u] ^ 1]);
      sum += cost[from[u] ^ 1];
    }
    cap[from[t] ^ 1] -= flow;
    cap[from[t]] += flow;
    for (int u = to[from[t]]; u != s; u = to[from[u]]) {
      cap[from[u] ^ 1] -= flow;
      cap[from[u]] += flow;
    }
    res += sum * flow;
  }
  return res;
}

void link(int x, int y, int i, int j) {
  if (mvis[i][j] or str[i][j] == '#' or !str[i][j])
    return;
  mvis[i][j] = 1;
  add(id1[x][y], id2[i][j], 1, x + y - i - j);
  /* debug("%d %d %d %d\\n", x, y, i, j); */
  link(x, y, i + 1, j);
  link(x, y, i, j + 1);
}

int main() {
  int n = read, m = read;
  for (int i = 1; i <= n; i++)
    scanf("%s", str[i] + 1);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      if (str[i][j] == 'o')
        id1[i][j] = ++ip;
      if (str[i][j] != '#')
        id2[i][j] = ++ip;
    }
  int S = ++ip, T = ++ip;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      if (str[i][j] == 'o') {
        add(S, id1[i][j], 1, 0);
        link(i, j, i, j);
        for (int ii = 1; ii <= n; ii++)
          for (int jj = 1; jj <= m; jj++)
            mvis[ii][jj] = 0;
      }
      if (str[i][j] != '#')
        add(id2[i][j], T, 1, 0);
    }
  printf("%lld\\n", -mincostmaxflow(S, T));
}


Error: 0

Fixed submission:

/*
 * Author: Kewth

 * Date:
  echo -n '  ' && date +%Y.%m.%d # Type "!!sh" in Vim.

 * Solution:
  To be updated after "Accept".

 * Digression:

 * CopyRight:
   __  __                  __   __
  |  |/  |.-----.--.--.--.|  |_|  |--.
  |     < |  -__|  |  |  ||   _|     |
  |__|\\__||_____|________||____|__|__|

 */

#include <algorithm>
#include <cstdio>
#include <queue>
#define debug(...) fprintf(stderr, __VA_ARGS__)

typedef long long ll;

static struct {
  inline operator int() {
    int x;
    return scanf("%d", &x), x;
  }
  inline operator ll() {
    ll x;
    return scanf("%lld", &x), x;
  }
  template <class T> inline void operator()(T &x) { x = *this; }
  template <class T, class... A> inline void operator()(T &x, A &...a) {
    x = *this;
    this->operator()(a...);
  }
} read;

const int Maxn = 55;
char str[Maxn][Maxn];
int id1[Maxn][Maxn], id2[Maxn][Maxn], ip;
bool mvis[Maxn][Maxn];

const int maxn = 2605, maxm = 252605;
int head[maxn], nxt[maxm << 1], to[maxm << 1], cap[maxm << 1], cost[maxm << 1],
    hp = 1;

inline void add(int u, int v, int ca, int co) {
  if ((hp & 1) and !ca)
    return;
  nxt[++hp] = head[u];
  head[u] = hp;
  to[hp] = v;
  cap[hp] = ca;
  cost[hp] = co;
  if (!(hp & 1))
    add(v, u, 0, -co);
}

ll dis[maxn];
bool inq[maxn], vis[maxn];
int from[maxn];
bool spfa(int s, int t) {
  std::queue<int> q;
  std::fill(dis, dis + t + 1, 1000000000000000000);
  std::fill(inq, inq + t + 1, 0);
  dis[s] = 0;
  q.push(s);
  while (!q.empty()) {
    int u = q.front();
    vis[u] = 1;
    q.pop();
    inq[u] = 0;
    for (int i = head[u]; i; i = nxt[i])
      if (cap[i] and dis[u] + cost[i] < dis[to[i]]) {
        dis[to[i]] = dis[u] + cost[i];
        from[to[i]] = i ^ 1;
        if (!inq[to[i]]) {
          q.push(to[i]);
          inq[to[i]] = 1;
        }
      }
  }
  return dis[t] < 1000000000000000000;
}

ll mincostmaxflow(int s, int t) {
  ll res = 0;
  while (spfa(s, t)) {
    int flow = cap[from[t] ^ 1];
    ll sum = cost[from[t] ^ 1];
    for (int u = to[from[t]]; u != s; u = to[from[u]]) {
      flow = std::min(flow, cap[from[u] ^ 1]);
      sum += cost[from[u] ^ 1];
    }
    cap[from[t] ^ 1] -= flow;
    cap[from[t]] += flow;
    for (int u = to[from[t]]; u != s; u = to[from[u]]) {
      cap[from[u] ^ 1] -= flow;
      cap[from[u]] += flow;
    }
    res += sum * flow;
  }
  return res;
}

void link(int x, int y, int i, int j) {
  if (str[i][j] == '#' or !str[i][j])
    return;
  mvis[i][j] = 1;
  add(id1[x][y], id2[i][j], 1, x + y - i - j);
  /* debug("%d %d %d %d\\n", x, y, i, j); */
  link(x, y, i + 1, j);
  link(x, y, i, j + 1);
}

int main() {
  int n = read, m = read;
  for (int i = 1; i <= n; i++)
    scanf("%s", str[i] + 1);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      if (str[i][j] == 'o')
        id1[i][j] = ++ip;
      if (str[i][j] != '#')
        id2[i][j] = ++ip;
    }
  int S = ++ip, T = ++ip;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      if (str[i][j] == 'o') {
        add(S, id1[i][j], 1, 0);
        link(i, j, i, j);
      }
      if (str[i][j] != '#')
        add(id2[i][j], T, 1, 0);
    }
  printf("%lld\\n", -mincostmaxflow(S, T));
}