Problem p01543 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <tuple>
#include <typeinfo>
#include <vector>

using namespace std;

typedef long long ll;
const int MAX_V = 110;
const int INT_INF = 1 << 30;
typedef pair<int, int> P;
typedef tuple<int, int, int> T;

int G[MAX_V + 1][MAX_V + 1];
int h[MAX_V * 2 + 2], dist[MAX_V * 2 + 2];
int prevv[MAX_V * 2 + 2];
bool used[MAX_V * 2 + 2];
bool flow[MAX_V + 1][MAX_V + 1] = {};

int bit_matching_cost(int l, int r) {
  int min_f = 0;
  for (int i = 0; i < l; i++) {
    for (int j = 0; j < r; j++) {
      min_f = min(min_f, G[i][j]);
    }
  }
  for (int i = 0; i < l; i++) {
    for (int j = 0; j < r; j++) {
      G[i][j] -= min_f;
    }
  }
  for (int i = 0; i < l; i++) {
    G[i][r] = 0;
    flow[i][r] = true;
  }
  for (int i = 0; i < r; i++) {
    G[l][i] = 0;
    flow[l][i] = true;
  }
  G[l][r] = INT_INF;
  flow[l][r] = false;
  int res = 0;
  fill_n(h, l + r + 2, 0);
  while (true) {
    fill_n(dist, l + r + 2, INT_INF);
    dist[l + r + 1] = 0;
    fill_n(used, l + r + 2, false);
    while (true) {
      int v = -1;
      for (int i = 0; i < l + r + 2; i++) {
        if (!used[i] && (v == -1 || dist[i] < dist[v])) {
          v = i;
        }
      }
      if (v == -1)
        break;
      if (v < l + 1) {
        used[v] = true;
        for (int i = l + 1; i < l + r + 2; i++) {
          if (!flow[v][i - (l + 1)] &&
              dist[i] > dist[v] + G[v][i - (l + 1)] + h[v] - h[i]) {
            dist[i] = dist[v] + G[v][i - (l + 1)] + h[v] - h[i];
            prevv[i] = v;
          }
        }
      } else {
        used[v] = true;
        for (int i = 0; i < l + 1; i++) {
          if (flow[i][v - (l + 1)] &&
              dist[i] > dist[v] - G[i][v - (l + 1)] + h[v] - h[i]) {
            dist[i] = dist[v] - G[i][v - (l + 1)] + h[v] - h[i];
            prevv[i] = v;
          }
        }
      }
    }
    if (dist[l] >= INT_INF) {
      break;
    }
    for (int v = 0; v < l + r + 2; v++) {
      h[v] += dist[v];
    }
    res += h[l];
    res += min_f;
    for (int v = l; v != l + r + 1; v = prevv[v]) {
      if (v < l + 1) {
        flow[v][prevv[v] - (l + 1)] = false;
      } else {
        flow[prevv[v + l + 1]][v - (l + 1)] = true;
      }
    }
  }
  return res;
}
int cost[MAX_V][MAX_V];

const int MAX_N = 105;
int N;
int W[MAX_N][MAX_N], E[MAX_N][MAX_N];
bool F[MAX_N][MAX_N], F2[MAX_N][MAX_N];

int main(int argc, char *argv[]) {
  cin >> N;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      scanf("%d", &(W[i][j]));
    }
  }
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      scanf("%d", &(E[i][j]));
    }
  }
  for (int i = 0; i < N; i++) {
    string s;
    cin >> s;
    for (int j = 0; j < N; j++) {
      F[i][j] = (s[j] == 'o');
    }
  }

  int f = 0;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      if (F[i][j]) {
        G[i][j] = -E[i][j];
        f += E[i][j];
      } else {
        G[i][j] = W[i][j];
      }
    }
  }
  f += bit_matching_cost(N, N);
  int c = 0;
  vector<T> q;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      if (F[i][j] != flow[i][j]) {
        c++;
        q.push_back(T(i, j, F[i][j]));
      }
    }
  }
  printf("%d\n%d\n", f, c);
  for (T t : q) {
    printf("%d %d %s\n", get<0>(t) + 1, get<1>(t) + 1,
           get<2>(t) ? "erase" : "write");
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <tuple>
#include <typeinfo>
#include <vector>

using namespace std;

typedef long long ll;
const int MAX_V = 110;
const int INT_INF = 1 << 30;
typedef pair<int, int> P;
typedef tuple<int, int, int> T;

int G[MAX_V + 1][MAX_V + 1];
int h[MAX_V * 2 + 2], dist[MAX_V * 2 + 2];
int prevv[MAX_V * 2 + 2];
bool used[MAX_V * 2 + 2];
bool flow[MAX_V + 1][MAX_V + 1] = {};

int bit_matching_cost(int l, int r) {
  int min_f = 0;
  for (int i = 0; i < l; i++) {
    for (int j = 0; j < r; j++) {
      min_f = min(min_f, G[i][j]);
    }
  }
  for (int i = 0; i < l; i++) {
    for (int j = 0; j < r; j++) {
      G[i][j] -= min_f;
    }
  }
  for (int i = 0; i < l; i++) {
    G[i][r] = 0;
    flow[i][r] = true;
  }
  for (int i = 0; i < r; i++) {
    G[l][i] = 0;
    flow[l][i] = true;
  }
  G[l][r] = INT_INF;
  flow[l][r] = false;
  int res = 0;
  fill_n(h, l + r + 2, 0);
  while (true) {
    fill_n(dist, l + r + 2, INT_INF);
    dist[l + r + 1] = 0;
    fill_n(used, l + r + 2, false);
    while (true) {
      int v = -1;
      for (int i = 0; i < l + r + 2; i++) {
        if (!used[i] && (v == -1 || dist[i] < dist[v])) {
          v = i;
        }
      }
      if (v == -1)
        break;
      if (v < l + 1) {
        used[v] = true;
        for (int i = l + 1; i < l + r + 2; i++) {
          if (!flow[v][i - (l + 1)] &&
              dist[i] > dist[v] + G[v][i - (l + 1)] + h[v] - h[i]) {
            dist[i] = dist[v] + G[v][i - (l + 1)] + h[v] - h[i];
            prevv[i] = v;
          }
        }
      } else {
        used[v] = true;
        for (int i = 0; i < l + 1; i++) {
          if (flow[i][v - (l + 1)] &&
              dist[i] > dist[v] - G[i][v - (l + 1)] + h[v] - h[i]) {
            dist[i] = dist[v] - G[i][v - (l + 1)] + h[v] - h[i];
            prevv[i] = v;
          }
        }
      }
    }
    if (dist[l] >= INT_INF) {
      break;
    }
    for (int v = 0; v < l + r + 2; v++) {
      h[v] += dist[v];
    }
    res += h[l];
    res += min_f;
    for (int v = l; v != l + r + 1; v = prevv[v]) {
      if (v < l + 1) {
        flow[v][prevv[v] - (l + 1)] = false;
      } else {
        flow[prevv[v]][v - (l + 1)] = true;
      }
    }
  }
  return res;
}
int cost[MAX_V][MAX_V];

const int MAX_N = 105;
int N;
int W[MAX_N][MAX_N], E[MAX_N][MAX_N];
bool F[MAX_N][MAX_N], F2[MAX_N][MAX_N];

int main(int argc, char *argv[]) {
  cin >> N;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      scanf("%d", &(W[i][j]));
    }
  }
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      scanf("%d", &(E[i][j]));
    }
  }
  for (int i = 0; i < N; i++) {
    string s;
    cin >> s;
    for (int j = 0; j < N; j++) {
      F[i][j] = (s[j] == 'o');
    }
  }

  int f = 0;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      if (F[i][j]) {
        G[i][j] = -E[i][j];
        f += E[i][j];
      } else {
        G[i][j] = W[i][j];
      }
    }
  }
  f += bit_matching_cost(N, N);
  int c = 0;
  vector<T> q;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      if (F[i][j] != flow[i][j]) {
        c++;
        q.push_back(T(i, j, F[i][j]));
      }
    }
  }
  printf("%d\n%d\n", f, c);
  for (T t : q) {
    printf("%d %d %s\n", get<0>(t) + 1, get<1>(t) + 1,
           get<2>(t) ? "erase" : "write");
  }
  return 0;
}