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

#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <sstream>
#include <vector>
using namespace std;

#define all(c) (c).begin(), (c).end()
#define loop(i, a, b) for (int i = (a); i < int(b); i++)
#define rep(i, b) loop(i, 0, b)

// Verify : http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2429
struct PrimalDual {
  typedef int Capacity;
  typedef int Cost;
  struct Edge;
  int n;
  vector<vector<Edge>> g;
  enum : Cost { inf = 1 << 29 };

  struct Edge {
    int dst;
    Capacity cap;
    Capacity cap_orig;
    Cost cost;
    int revEdge;
    bool isRev;
    Edge(int dst, Capacity cap, Cost cost, int revEdge, bool isRev)
        : dst(dst), cap(cap), cap_orig(cap), cost(cost), revEdge(revEdge),
          isRev(isRev) {}
  };

  PrimalDual(int n_) : n(n_), g(vector<vector<Edge>>(n_)) {}

  void add_edge(int src, int dst, Capacity cap, Cost cost) {
    g[src].push_back(Edge(dst, cap, cost, g[dst].size(), false));
    g[dst].push_back(Edge(src, 0, -cost, g[src].size() - 1, true));
  }

  int min_cost_flow(int s, int t, int f) {
    int res = 0;
    vector<Cost> h(g.size()), dist(g.size());
    vector<int> prevv(g.size()), preve(g.size());
    while (f > 0) {
      typedef pair<Cost, int> pcv;
      priority_queue<pcv, vector<pcv>, greater<pcv>> q;
      dist.assign(n, inf);
      dist[s] = 0;
      q.push(pcv(0, s));
      while (q.size()) {
        pcv p = q.top();
        q.pop();
        int v = p.second;
        if (dist[v] < p.first)
          continue;
        rep(i, g[v].size()) {
          Edge &e = g[v][i];
          if (e.cap > 0 && dist[e.dst] > dist[v] + e.cost + h[v] - h[e.dst]) {
            dist[e.dst] = dist[v] + e.cost + h[v] - h[e.dst];
            prevv[e.dst] = v;
            preve[e.dst] = i;
            q.push(pcv(dist[e.dst], e.dst));
          }
        }
      }
      if (dist[t] == inf) {
        return -1;
      }
      rep(v, n) h[v] += dist[v];
      // s-t 間最短路に沿って目一杯流す
      int d = f;
      for (int v = t; v != s; v = prevv[v]) {
        d = min(d, g[prevv[v]][preve[v]].cap);
      }
      f -= d;
      res += d * h[t];
      for (int v = t; v != s; v = prevv[v]) {
        Edge &e = g[prevv[v]][preve[v]];
        e.cap -= d;
        g[v][e.revEdge].cap += d;
      }
    }
    return res;
  }

  // 流れたフロー=元々の容量-現在の容量を表示
  void view() {
    rep(i, g.size()) {
      rep(j, g[i].size()) if (!g[i][j].isRev) {
        Edge &e = g[i][j];
        printf("%3d->%3d (flow:%d)\\n", i, e.dst, e.cap_orig - e.cap);
      }
    }
  }
};

int W[111][111], E[111][111];
char f[111][111];
int n;
int N;

void solve() {
  int C = 0;
  rep(i, n) rep(j, n) {
    if (f[i][j] == 'o')
      C += E[i][j];
  }
  PrimalDual mcf(n * 2 + 2);
  int s = n * 2, t = n * 2 + 1;
  rep(i, n) {
    mcf.add_edge(s, i, 1, 0);
    mcf.add_edge(i + n, t, 1, 0);
  }
  rep(i, n) rep(j, n) {
    if (f[i][j] == 'o') {
      mcf.add_edge(i, j + n, 1, -E[i][j]);
    } else {
      mcf.add_edge(i, j + n, 1, W[i][j]);
    }
  }
  printf("%d\\n", C + mcf.min_cost_flow(s, t, n));
  static int ans[10000][3];
  int cnt = 0;

  rep(i, mcf.g.size()) {
    rep(j, mcf.g[i].size()) {
      auto &e = mcf.g[i][j];
      if (e.isRev || e.cost == 0)
        continue;
      int r = i, c = e.dst - n;
      if (f[r][c] == 'o' && e.cap != 0) {
        cnt++;
        ans[cnt][0] = r + 1;
        ans[cnt][1] = c + 1;
        ans[cnt][2] = 0;
      } else if (f[r][c] == '.' && e.cap == 0) {
        cnt++;
        ans[cnt][0] = r + 1;
        ans[cnt][1] = c + 1;
        ans[cnt][2] = 1;
      }
    }
  }
  printf("%d\\n", cnt);
  rep(i, cnt) {
    printf("%d %d %s\\n", ans[i][0], ans[i][1],
           ans[i][2] == 0 ? "erase" : "write");
  }
}

int main() {
  while (cin >> n) {
    N = n * 2 + 2;
    rep(i, n) rep(j, n) cin >> W[i][j];
    rep(i, n) rep(j, n) cin >> E[i][j];
    rep(i, n) cin >> f[i];
    solve();
  }
}

Error: WA

Fixed submission:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <sstream>
#include <vector>
using namespace std;

#define all(c) (c).begin(), (c).end()
#define loop(i, a, b) for (int i = (a); i < int(b); i++)
#define rep(i, b) loop(i, 0, b)

// Verify : http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2429
struct PrimalDual {
  typedef int Capacity;
  typedef int Cost;
  struct Edge;
  int n;
  vector<vector<Edge>> g;
  enum : Cost { inf = 1 << 29 };

  struct Edge {
    int dst;
    Capacity cap, cap_orig;
    Cost cost;
    int revEdge;
    bool isRev;
    Edge(int dst, Capacity cap, Cost cost, int revEdge, bool isRev)
        : dst(dst), cap(cap), cap_orig(cap), cost(cost), revEdge(revEdge),
          isRev(isRev) {}
  };

  PrimalDual(int n_) : n(n_), g(vector<vector<Edge>>(n_)) {}

  void add_edge(int src, int dst, Capacity cap, Cost cost) {
    g[src].push_back(Edge(dst, cap, cost, g[dst].size(), false));
    g[dst].push_back(Edge(src, 0, -cost, g[src].size() - 1, true));
  }

  int min_cost_flow(int s, int t, int f) {
    int res = 0;
    vector<Cost> h(n), dist(n);
    vector<int> prevv(n), preve(n);
    while (f > 0) {
      typedef pair<Cost, int> pcv;
      priority_queue<pcv, vector<pcv>, greater<pcv>> q;
      dist.assign(n, inf);
      dist[s] = 0;
      q.push(pcv(0, s));
      while (q.size()) {
        pcv p = q.top();
        q.pop();
        int v = p.second;
        if (dist[v] < p.first)
          continue;
        rep(i, g[v].size()) {
          Edge &e = g[v][i];
          if (e.cap > 0 && dist[e.dst] > dist[v] + e.cost + h[v] - h[e.dst]) {
            dist[e.dst] = dist[v] + e.cost + h[v] - h[e.dst];
            prevv[e.dst] = v;
            preve[e.dst] = i;
            q.push(pcv(dist[e.dst], e.dst));
          }
        }
      }
      if (dist[t] == inf) {
        return -1;
      }
      rep(v, n) h[v] += dist[v];
      // s-t 間最短路に沿って目一杯流す
      int d = f;
      for (int v = t; v != s; v = prevv[v]) {
        d = min(d, g[prevv[v]][preve[v]].cap);
      }
      f -= d;
      res += d * h[t];
      for (int v = t; v != s; v = prevv[v]) {
        Edge &e = g[prevv[v]][preve[v]];
        e.cap -= d;
        g[v][e.revEdge].cap += d;
      }
    }
    return res;
  }

  // 流れたフロー=元々の容量-現在の容量を表示
  void view() {
    rep(i, g.size()) {
      rep(j, g[i].size()) if (!g[i][j].isRev) {
        Edge &e = g[i][j];
        printf("%3d->%3d (flow:%d)\\n", i, e.dst, e.cap_orig - e.cap);
      }
    }
  }
};

int W[111][111], E[111][111];
char f[111][111];
int n;
int N;

void solve() {
  int C = 0;
  rep(i, n) rep(j, n) {
    if (f[i][j] == 'o')
      C += E[i][j];
  }
  PrimalDual mcf(n * 2 + 2);
  int s = n * 2, t = n * 2 + 1;
  rep(i, n) {
    mcf.add_edge(s, i, 1, 0);
    mcf.add_edge(i + n, t, 1, 0);
  }
  rep(i, n) rep(j, n) {
    if (f[i][j] == 'o') {
      mcf.add_edge(i, j + n, 1, -E[i][j]);
    } else {
      mcf.add_edge(i, j + n, 1, W[i][j]);
    }
  }
  printf("%d\\n", C + mcf.min_cost_flow(s, t, n));
  static int ans[10000][3];
  int cnt = 0;

  rep(i, mcf.n) {
    rep(j, mcf.n) {
      auto &e = mcf.g[i][j];
      if (e.isRev || e.cost == 0)
        continue;
      if (f[i][e.dst - n] == 'o' && e.cap != 0) {
        cnt++;
        ans[cnt][0] = i + 1;
        ans[cnt][1] = e.dst - n + 1;
        ans[cnt][2] = 0;
      } else if (f[i][e.dst - n] == '.' && e.cap == 0) {
        cnt++;
        ans[cnt][0] = i + 1;
        ans[cnt][1] = e.dst - n + 1;
        ans[cnt][2] = 1;
      }
    }
  }
  printf("%d\\n", cnt);
  rep(i, cnt) {
    printf("%d %d %s\\n", ans[i][0], ans[i][1],
           ans[i][2] == 0 ? "erase" : "write");
  }
}

int main() {
  while (cin >> n) {
    N = n * 2 + 2;
    rep(i, n) rep(j, n) cin >> W[i][j];
    rep(i, n) rep(j, n) cin >> E[i][j];
    rep(i, n) cin >> f[i];
    solve();
  }
}