Problem p02561 (C++)

Buggy submission (status: Runtime Error):
#include "algorithm"
#include "bitset"
#include "cassert"
#include "climits"
#include "cmath"
#include "cstdio"
#include "ctime"
#include "functional"
#include "iomanip"
#include "iostream"
#include "list"
#include "map"
#include "numeric"
#include "queue"
#include "random"
#include "set"
#include "stack"
#include "string"
#include "unordered_map"
#include "unordered_set"

using namespace std;

// constexpr long long int MOD = 1000000007;
// constexpr int MOD = 1000000007;
// constexpr int MOD = 998244353;
constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-12;

// int N, M, K, T, H, W, L, R;
long long int N, M, K, T, H, W, L, R;

class Edge {
public:
  long long int to;
  long long int max_flow;
  long long int rev;
};

class Dinic {
  int V;
  bool directed;

public:
  vector<vector<Edge>> edge;
  vector<int> depth;
  vector<int> index;
  Dinic(int n, bool D) {
    n++;
    V = n;
    edge.resize(V);
    depth.resize(V);
    index.resize(V);
    directed = D;
    return;
  }
  void Add_Edge(int l, int r, int max_flow) {
    edge[l].push_back({r, max_flow, (int)edge[r].size()});
    if (directed) {
      edge[r].push_back({l, 0, (int)edge[l].size() - 1});
    } else {
      edge[r].push_back({l, max_flow, (int)edge[l].size() - 1});
    }
    return;
  }
  void Check_Depth(int s) {
    for (int i = 0; i < V; i++) {
      depth[i] = INT_MAX;
    }
    depth[s] = 0;
    queue<int> Q;
    Q.push(s);
    while (!Q.empty()) {
      int cn = Q.front();
      Q.pop();
      for (auto i : edge[cn]) {
        if (i.max_flow > 0 && depth[i.to] == INT_MAX) {
          depth[i.to] = depth[cn] + 1;
          Q.push(i.to);
        }
      }
    }
    return;
  }
  long long int max_flow(int v, int g, long long int ret) {
    if (v == g) {
      return ret;
    }
    for (int i = index[v]; i < edge[v].size(); i++) {
      if (edge[v][i].max_flow > 0 && depth[v] < depth[edge[v][i].to]) {
        long long int d =
            max_flow(edge[v][i].to, g, min(ret, edge[v][i].max_flow));
        if (d > 0) {
          edge[v][i].max_flow -= d;
          edge[edge[v][i].to][edge[v][i].rev].max_flow += d;
          return d;
        }
      }
    }
    return 0;
  }
  long long Solve(int s, int g) {
    long long int ret = 0;
    while (1) {
      Check_Depth(s);
      if (depth[g] == INT_MAX) {
        return ret;
      }
      for (int i = 0; i < V; i++) {
        index[i] = 0;
      }
      long long int add = 0;
      while ((add = max_flow(s, g, INT_MAX)) > 0) {
        ret += add;
      }
    }
    return ret;
  }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  cin >> H >> W;
  vector<string> s(H);
  for (auto &i : s)
    cin >> i;
  Dinic d(H * W + 2, true);
  int dir[] = {1, 0, -1, 0, 1};
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (s[i][j] == '#')
        continue;
      if ((i + j) & 1) {
        d.Add_Edge(H * W, i * W + j, 1);
        for (int k = 0; k < 4; k++) {
          int ny = i + dir[k];
          int nx = j + dir[k + 1];
          if (ny < 0 || nx < 0 || ny >= H || nx >= W)
            continue;
          d.Add_Edge(i * W + j, ny * W + nx, 1);
        }
      } else {
        d.Add_Edge(i * W + j, H * W + 1, 1);
      }
    }
  }
  cout << d.Solve(H * W, H * W + 1) << endl;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if ((i + j) & 1) {
        int num = i * W + j;
        for (auto k : d.edge[num]) {
          if (k.max_flow == 0) {
            if (num + W == k.to) {
              s[i][j] = 'v';
              s[i + 1][j] = '^';
            } else if (num + 1 == k.to) {
              s[i][j] = '>';
              s[i][j + 1] = '<';
            } else if (num - W == k.to) {
              s[i][j] = '^';
              s[i - 1][j] = 'v';
            } else {
              s[i][j] = '<';
              s[i][j - 1] = '>';
            }
          }
        }
      }
    }
  }
  for (auto i : s)
    cout << i << endl;
}

Fixed submission:
#include "algorithm"
#include "bitset"
#include "cassert"
#include "climits"
#include "cmath"
#include "cstdio"
#include "ctime"
#include "functional"
#include "iomanip"
#include "iostream"
#include "list"
#include "map"
#include "numeric"
#include "queue"
#include "random"
#include "set"
#include "stack"
#include "string"
#include "unordered_map"
#include "unordered_set"

using namespace std;

// constexpr long long int MOD = 1000000007;
// constexpr int MOD = 1000000007;
// constexpr int MOD = 998244353;
constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-12;

// int N, M, K, T, H, W, L, R;
long long int N, M, K, T, H, W, L, R;

class Edge {
public:
  long long int to;
  long long int max_flow;
  long long int rev;
};

class Dinic {
  int V;
  bool directed;

public:
  vector<vector<Edge>> edge;
  vector<int> depth;
  vector<int> index;
  Dinic(int n, bool D) {
    n++;
    V = n;
    edge.resize(V);
    depth.resize(V);
    index.resize(V);
    directed = D;
    return;
  }
  void Add_Edge(int l, int r, int max_flow) {
    edge[l].push_back({r, max_flow, (int)edge[r].size()});
    if (directed) {
      edge[r].push_back({l, 0, (int)edge[l].size() - 1});
    } else {
      edge[r].push_back({l, max_flow, (int)edge[l].size() - 1});
    }
    return;
  }
  void Check_Depth(int s) {
    for (int i = 0; i < V; i++) {
      depth[i] = INT_MAX;
    }
    depth[s] = 0;
    queue<int> Q;
    Q.push(s);
    while (!Q.empty()) {
      int cn = Q.front();
      Q.pop();
      for (auto i : edge[cn]) {
        if (i.max_flow > 0 && depth[i.to] == INT_MAX) {
          depth[i.to] = depth[cn] + 1;
          Q.push(i.to);
        }
      }
    }
    return;
  }
  long long int max_flow(int v, int g, long long int ret) {
    if (v == g) {
      return ret;
    }
    for (int i = index[v]; i < edge[v].size(); i++) {
      if (edge[v][i].max_flow > 0 && depth[v] < depth[edge[v][i].to]) {
        long long int d =
            max_flow(edge[v][i].to, g, min(ret, edge[v][i].max_flow));
        if (d > 0) {
          edge[v][i].max_flow -= d;
          edge[edge[v][i].to][edge[v][i].rev].max_flow += d;
          return d;
        }
      }
    }
    return 0;
  }
  long long Solve(int s, int g) {
    long long int ret = 0;
    while (1) {
      Check_Depth(s);
      if (depth[g] == INT_MAX) {
        return ret;
      }
      for (int i = 0; i < V; i++) {
        index[i] = 0;
      }
      long long int add = 0;
      while ((add = max_flow(s, g, INT_MAX)) > 0) {
        ret += add;
      }
    }
    return ret;
  }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  cin >> H >> W;
  vector<string> s(H);
  for (auto &i : s)
    cin >> i;
  Dinic d(H * W + 2, true);
  int dir[] = {1, 0, -1, 0, 1};
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (s[i][j] == '#')
        continue;
      if ((i + j) & 1) {
        d.Add_Edge(H * W, i * W + j, 1);
        for (int k = 0; k < 4; k++) {
          int ny = i + dir[k];
          int nx = j + dir[k + 1];
          if (ny < 0 || nx < 0 || ny >= H || nx >= W)
            continue;
          d.Add_Edge(i * W + j, ny * W + nx, 1);
        }
      } else {
        d.Add_Edge(i * W + j, H * W + 1, 1);
      }
    }
  }
  cout << d.Solve(H * W, H * W + 1) << endl;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if ((i + j) & 1) {
        int num = i * W + j;
        for (auto k : d.edge[num]) {
          if (k.max_flow == 0) {
            if (k.to == H * W)
              continue;
            if (num + W == k.to) {
              s[i][j] = 'v';
              s[i + 1][j] = '^';
            } else if (num + 1 == k.to) {
              s[i][j] = '>';
              s[i][j + 1] = '<';
            } else if (num - W == k.to) {
              s[i][j] = '^';
              s[i - 1][j] = 'v';
            } else {
              s[i][j] = '<';
              s[i][j - 1] = '>';
            }
          }
        }
      }
    }
  }
  for (auto i : s)
    cout << i << endl;
}