Problem p01543 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <iostream>
#include <queue>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

const int INF = (1 << 28);

class Edge {
public:
  int src, dst, cst, cap, rev;
  Edge(int src, int dst, int cst, int cap, int rev)
      : src(src), dst(dst), cst(cst), cap(cap), rev(rev) {}
};

typedef vector<vector<Edge>> Graph;

void addEdge(int u, int v, int cap, int cost, Graph &graph) {
  graph[u].push_back(Edge(u, v, cost, cap, graph[v].size()));
  graph[v].push_back(Edge(v, u, -cost, 0, graph[u].size() - 1));
}

pair<int, int> minimumCostFlow(int S, int T, int L, Graph &graph) {
  int V = graph.size();
  vector<int> dist(V), prevv(V), preve(V);

  int res = 0, fw = 0;
  while (1) {
    fill(dist.begin(), dist.end(), INF);
    dist[S] = 0;
    bool update = true;

    while (update) {
      update = false;
      for (int v = 0; v < V; v++) {
        if (dist[v] == INF)
          continue;

        for (int i = 0; i < graph[v].size(); i++) {
          Edge &e = graph[v][i];
          int cost = e.cst;
          if (graph[e.dst][e.rev].cap != 0)
            cost = 0;

          if (e.cap > 0 && dist[e.dst] > dist[e.src] + cost) {
            dist[e.dst] = dist[e.src] + cost;
            prevv[e.dst] = e.src;
            preve[e.dst] = i;
            update = true;
          }
        }
      }
    }

    if (dist[T] == INF)
      break;

    int f = INF;
    for (int v = T; v != S; v = prevv[v])
      f = min(f, graph[prevv[v]][preve[v]].cap);

    res += dist[T];
    fw += f;

    for (int v = T; v != S; v = prevv[v]) {
      Edge &e = graph[prevv[v]][preve[v]];
      e.cap -= f;
      graph[v][e.rev].cap += f;
    }

    if (fw >= L)
      break;
  }

  return make_pair(res, fw);
}

int ecst[100][100], icst[100][100];
int main() {
  int N;
  cin >> N;
  for (int i = 0; i < N; i++)
    for (int j = 0; j < N; j++)
      cin >> icst[i][j];

  for (int i = 0; i < N; i++)
    for (int j = 0; j < N; j++)
      cin >> ecst[i][j];

  string field[100];
  for (int i = 0; i < N; i++)
    cin >> field[i];

  Graph graph(N * 2 + 2);
  for (int i = 0; i < N; i++) {
    addEdge(N * 2, i, 1, 0, graph);
    addEdge(N + i, N * 2 + 1, 1, 0, graph);
  }

  for (int i = 0; i < N; i++)
    for (int j = 0; j < N; j++) {
      int cst = 0;
      for (int k = 0; k < N; k++) {
        if (field[k][j] == 'o')
          cst += ecst[k][j];
        if (field[i][k] == 'o')
          cst += ecst[i][k];
      }

      if (field[i][j] == 'o')
        cst -= 2 * ecst[i][j];
      if (field[i][j] == '.')
        cst += 2 * icst[i][j];

      addEdge(j, i + N, 1, cst, graph);
    }

  pair<int, int> fw = minimumCostFlow(N * 2, N * 2 + 1, N, graph);

  cout << fw.first / 2 << endl;

  int c = 0;
  stringstream ss;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < graph[i].size(); j++) {
      Edge &e = graph[i][j];

      if (e.dst < N || e.dst >= N * 2)
        continue;

      if (field[e.dst - N][e.src] == 'o' && e.cap == 1) {
        c++;
        ss << e.dst + 1 - N << " " << e.src + 1 << " erase" << endl;
      }
      if (field[e.dst - N][e.src] == '.' && e.cap == 0) {
        c++;
        ss << e.dst + 1 - N << " " << e.src + 1 << " write" << endl;
      }
    }
  }

  cout << c << endl;
  cout << ss.str();

  // system("pause");
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <queue>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

const int INF = (1 << 28);

class Edge {
public:
  int src, dst, cst, cap, rev;
  Edge(int src, int dst, int cst, int cap, int rev)
      : src(src), dst(dst), cst(cst), cap(cap), rev(rev) {}
};

typedef vector<vector<Edge>> Graph;

void addEdge(int u, int v, int cap, int cost, Graph &graph) {
  graph[u].push_back(Edge(u, v, cost, cap, graph[v].size()));
  graph[v].push_back(Edge(v, u, -cost, 0, graph[u].size() - 1));
}

pair<int, int> minimumCostFlow(int S, int T, int L, Graph &graph) {
  int V = graph.size();
  vector<int> dist(V), prevv(V), preve(V);

  int res = 0, fw = 0;

  while (1) {
    fill(dist.begin(), dist.end(), INF);
    dist[S] = 0;
    bool update = true;

    while (update) {
      update = false;
      for (int v = 0; v < V; v++) {
        if (dist[v] == INF)
          continue;

        for (int i = 0; i < graph[v].size(); i++) {
          Edge &e = graph[v][i];
          int cost = e.cst;
          if (graph[e.dst][e.rev].cap != 0)
            cost = 0;

          if (e.cap > 0 && dist[e.dst] > dist[e.src] + cost) {
            dist[e.dst] = dist[e.src] + cost;
            prevv[e.dst] = e.src;
            preve[e.dst] = i;
            update = true;
          }
        }
      }
    }

    if (dist[T] == INF)
      break;

    int f = INF;
    for (int v = T; v != S; v = prevv[v])
      f = min(f, graph[prevv[v]][preve[v]].cap);

    res += dist[T];
    fw += f;

    for (int v = T; v != S; v = prevv[v]) {
      Edge &e = graph[prevv[v]][preve[v]];
      e.cap -= f;
      graph[v][e.rev].cap += f;
    }

    if (fw >= L)
      break;
  }

  return make_pair(res, fw);
}

int ecst[100][100], icst[100][100];
int main() {
  int N;
  while (cin >> N, N) {
    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++)
        cin >> ecst[j][i];

    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++)
        cin >> icst[j][i];

    string field[100];
    for (int i = 0; i < N; i++)
      cin >> field[i];

    int res = 0;
    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++) {
        if (field[i][j] == 'o') {
          res += ecst[j][i];
        }
      }

    Graph graph(N * N + 2);
    for (int i = 0; i < N; i++) {
      addEdge(N * N, i, 1, 0, graph);
      addEdge(N + i, N * N + 1, 1, 0, graph);
    }

    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++) {
        int cst;
        if (field[j][i] == 'o')
          cst = -ecst[j][i];
        else
          cst = icst[j][i];

        addEdge(j, i + N, 1, cst, graph);
      }

    pair<int, int> fw = minimumCostFlow(N * N, N * N + 1, N, graph);

    int ans = res + fw.first;
    cout << ans << endl;

    if (ans == 0)
      cout << 0 << endl;

    else {
      int c = 0;
      stringstream ss;
      for (int i = 0; i < N; i++) {
        for (int j = 0; j < graph[i].size(); j++) {
          Edge &e = graph[i][j];

          if (e.src >= N * N || e.dst >= N * N)
            continue;

          if (field[e.src][e.dst - N] == 'o' && e.cap == 1) {
            c++;
            ss << e.src + 1 << " " << e.dst + 1 - N << " erase" << endl;
          }
          if (field[e.src][e.dst - N] == '.' && e.cap == 0) {
            c++;
            ss << e.src + 1 << " " << e.dst + 1 - N << " write" << endl;
          }
        }
      }

      cout << c << endl;
      cout << ss.str();
    }
  }
}