Problem p03099 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
int S = 0, T;
int N;
struct edge {
  int s, t, cap;
  long long v;
  int nxt;
} e[50005];
int e_cnt, last[405];
void addedge(int u, int v, int cap, long long l) {
  e[e_cnt] = (edge){u, v, cap, l, last[u]};
  last[u] = e_cnt++;
  e[e_cnt] = (edge){v, u, 0, -l, last[v]};
  last[v] = e_cnt++;
}
long long d[405];
int fa[405];
bool vis[405];
#define LIM -(1000000000000001ll)
bool dij() {
  for (int i = 0; i <= T; i++)
    d[i] = LIM;
  memset(vis, 0, sizeof(vis));
  d[S] = 0;
  for (int i = 0; i <= T; i++) {
    int x = -1;
    for (int j = 0; j <= T; j++)
      if (!vis[j] && (x == -1 || d[j] > d[x]))
        x = j;
    if (x == -1 || d[x] == LIM)
      break;
    vis[x] = 1;
    for (int i = last[x]; i != -1; i = e[i].nxt)
      if (!vis[e[i].t] && e[i].cap && d[e[i].t] < d[x] + e[i].v) {
        // assert(e[i].v<=0);
        d[e[i].t] = d[x] + e[i].v;
        fa[e[i].t] = i;
      }
  }
  return d[T] > LIM;
}
pair<int, long long> solve() {
  int flow = 0;
  long long cost = 0;
  long long r = 0;
  while (dij()) {
    flow++;
    int u = T;
    while (u != S) {
      e[fa[u]].cap = 0;
      e[fa[u] ^ 1].cap = 1;
      u = e[fa[u]].s;
    }
    r += d[T];
    cost += r;
    for (int i = 0; i < e_cnt; i++)
      e[i].v = d[e[i].s] + e[i].v - d[e[i].t];
  }
  return make_pair(flow, cost);
}
int x[85], y[85];
long long v[85];
int t[325], a[325], b[325];
int L[85][2], R[85][2];
int main() {
  freopen("e.in", "r", stdin);
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d%lld", &x[i], &y[i], &v[i]);
  }
  int m;
  scanf("%d", &m);
  for (int i = 1; i <= m; i++) {
    char c = getchar();
    while (c < 'A' || c > 'Z')
      c = getchar();
    if (c == 'L')
      t[i] = 0;
    if (c == 'R')
      t[i] = 1;
    if (c == 'D')
      t[i] = 2;
    if (c == 'U')
      t[i] = 3;
    scanf("%d%d", &a[i], &b[i]);
  }
  long long ans = 0;
  for (int supy = 1; supy <= n; supy++) {
    memset(R, 63, sizeof(R));
    for (int j = 1; j <= m; j++)
      if (b[j] < supy) {
        if (t[j] & 1)
          R[supy - b[j]][t[j] >> 1] = min(R[supy - b[j]][t[j] >> 1], a[j] - 1);
        else
          L[b[j] + 1][t[j] >> 1] = max(L[b[j] + 1][t[j] >> 1], a[j] + 1);
      }
    for (int i = 2; i <= supy; i++)
      for (int j = 0; j < 2; j++)
        L[i][j] = max(L[i][j], L[i - 1][j]);
    for (int i = supy - 1; i > 0; i--)
      for (int j = 0; j < 2; j++)
        R[i][j] = min(R[i][j], R[i + 1][j]);
    // for(int i=1;i<=supy;i++)printf("%d %d\n",L[i][0],R[i][0]);
    // for(int i=1;i<=supy;i++)printf("%d %d\n",L[i][1],R[i][1]);
    T = 2 * supy + 2 * n + 1;
    e_cnt = 0;
    memset(last, -1, sizeof(last));
    for (int i = 1; i <= supy; i++)
      addedge(S, i, 1, 0), addedge(i + supy, T, 1, 0);
    for (int i = 1; i <= n; i++)
      addedge(i + 2 * supy, i + n + 2 * supy, 1, v[i] - 1000000000000000ll);
    for (int i = 1; i <= supy; i++)
      for (int j = 1; j <= n; j++)
        if (x[j] >= L[i][0] && x[j] <= R[i][0])
          addedge(i, j + 2 * supy, 1, 0);
    for (int i = 1; i <= supy; i++)
      for (int j = 1; j <= n; j++)
        if (y[j] >= L[i][1] && y[j] <= R[i][1])
          addedge(j + n + 2 * supy, i + supy, 1, 0);
    pair<int, long long> res = solve();
    // printf("%d %d %lld\n",supy,res.first,res.second);
    res.second += supy * 1000000000000000ll;
    if (res.first == supy)
      ans = max(ans, res.second);
  }
  printf("%lld\n", ans);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
int S = 0, T;
int N;
struct edge {
  int s, t, cap;
  long long v;
  int nxt;
} e[50005];
int e_cnt, last[405];
void addedge(int u, int v, int cap, long long l) {
  e[e_cnt] = (edge){u, v, cap, l, last[u]};
  last[u] = e_cnt++;
  e[e_cnt] = (edge){v, u, 0, -l, last[v]};
  last[v] = e_cnt++;
}
long long d[405];
int fa[405];
bool vis[405];
#define LIM -(1000000000000001ll)
bool dij() {
  for (int i = 0; i <= T; i++)
    d[i] = LIM;
  memset(vis, 0, sizeof(vis));
  d[S] = 0;
  for (int i = 0; i <= T; i++) {
    int x = -1;
    for (int j = 0; j <= T; j++)
      if (!vis[j] && (x == -1 || d[j] > d[x]))
        x = j;
    if (x == -1 || d[x] == LIM)
      break;
    vis[x] = 1;
    for (int i = last[x]; i != -1; i = e[i].nxt)
      if (!vis[e[i].t] && e[i].cap && d[e[i].t] < d[x] + e[i].v) {
        // assert(e[i].v<=0);
        d[e[i].t] = d[x] + e[i].v;
        fa[e[i].t] = i;
      }
  }
  return d[T] > LIM;
}
pair<int, long long> solve() {
  int flow = 0;
  long long cost = 0;
  long long r = 0;
  while (dij()) {
    flow++;
    int u = T;
    while (u != S) {
      e[fa[u]].cap = 0;
      e[fa[u] ^ 1].cap = 1;
      u = e[fa[u]].s;
    }
    r += d[T];
    cost += r;
    for (int i = 0; i < e_cnt; i++)
      e[i].v = d[e[i].s] + e[i].v - d[e[i].t];
  }
  return make_pair(flow, cost);
}
int x[85], y[85];
long long v[85];
int t[325], a[325], b[325];
int L[85][2], R[85][2];
int main() {
  // freopen("e.in","r",stdin);
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d%lld", &x[i], &y[i], &v[i]);
  }
  int m;
  scanf("%d", &m);
  for (int i = 1; i <= m; i++) {
    char c = getchar();
    while (c < 'A' || c > 'Z')
      c = getchar();
    if (c == 'L')
      t[i] = 0;
    if (c == 'R')
      t[i] = 1;
    if (c == 'D')
      t[i] = 2;
    if (c == 'U')
      t[i] = 3;
    scanf("%d%d", &a[i], &b[i]);
  }
  long long ans = 0;
  for (int supy = 1; supy <= n; supy++) {
    memset(R, 63, sizeof(R));
    for (int j = 1; j <= m; j++)
      if (b[j] < supy) {
        if (t[j] & 1)
          R[supy - b[j]][t[j] >> 1] = min(R[supy - b[j]][t[j] >> 1], a[j] - 1);
        else
          L[b[j] + 1][t[j] >> 1] = max(L[b[j] + 1][t[j] >> 1], a[j] + 1);
      }
    for (int i = 2; i <= supy; i++)
      for (int j = 0; j < 2; j++)
        L[i][j] = max(L[i][j], L[i - 1][j]);
    for (int i = supy - 1; i > 0; i--)
      for (int j = 0; j < 2; j++)
        R[i][j] = min(R[i][j], R[i + 1][j]);
    // for(int i=1;i<=supy;i++)printf("%d %d\n",L[i][0],R[i][0]);
    // for(int i=1;i<=supy;i++)printf("%d %d\n",L[i][1],R[i][1]);
    T = 2 * supy + 2 * n + 1;
    e_cnt = 0;
    memset(last, -1, sizeof(last));
    for (int i = 1; i <= supy; i++)
      addedge(S, i, 1, 0), addedge(i + supy, T, 1, 0);
    for (int i = 1; i <= n; i++)
      addedge(i + 2 * supy, i + n + 2 * supy, 1, v[i] - 1000000000000000ll);
    for (int i = 1; i <= supy; i++)
      for (int j = 1; j <= n; j++)
        if (x[j] >= L[i][0] && x[j] <= R[i][0])
          addedge(i, j + 2 * supy, 1, 0);
    for (int i = 1; i <= supy; i++)
      for (int j = 1; j <= n; j++)
        if (y[j] >= L[i][1] && y[j] <= R[i][1])
          addedge(j + n + 2 * supy, i + supy, 1, 0);
    pair<int, long long> res = solve();
    // printf("%d %d %lld\n",supy,res.first,res.second);
    res.second += supy * 1000000000000000ll;
    if (res.first == supy)
      ans = max(ans, res.second);
  }
  printf("%lld\n", ans);
  return 0;
}