Problem p03020 (C++)

Buggy submission (status: Runtime Error):
#include <cassert>
#include <iostream>
#include <queue>
#include <vector>
#define SOURCE 0
#define SINK 1
#define INF 1000000000000000000LL
using namespace std;
long long n;
long long type[] = {2, 3, 4, 5};
struct edge {
  long long cost, from, to, revid, flow, cap;
  edge(long long fr, long long to, long long flo, long long cost, long long cap,
       long long id)
      : from(fr), to(to), cost(cost), flow(flo), cap(cap), revid(id) {}
  bool operator<(edge *other) { return cost < other->cost; }
};

long long gennode(bool redorblue, long long ind) {
  return 6 + redorblue * n + ind;
}
vector<edge *> edgelist;
vector<edge *> adjlist[2001];
long long pot[2001];
long long dist[2001];
edge *par[2001];
priority_queue<pair<long long, edge *>, vector<pair<long long, edge *>>,
               greater<pair<long long, edge *>>>
    pq;
bool find_aug_path() {
  for (long long i = 0; i < 2 * n + 6; i++)
    dist[i] = INF;
  pq.push(make_pair(0, new edge(SOURCE, SOURCE, 0, 0, 0, 0)));
  while (!pq.empty()) {
    edge *prioredge = pq.top().second;
    long long curdist = pq.top().first;
    long long curnode = prioredge->to;
    pq.pop();
    if (dist[curnode] == INF) {
      dist[curnode] = curdist;
      par[curnode] = prioredge;
      for (long long i = 0; i < adjlist[curnode].size(); i++) {
        edge *cur = adjlist[curnode][i];
        if (cur->cap - cur->flow > 0) {
          assert(curdist + cur->cost + pot[cur->from] - pot[cur->to] >= 0);
          pq.push(make_pair(curdist + cur->cost + pot[cur->from] - pot[cur->to],
                            cur));
        }
      }
    }
  }
  /*cout << "OBTAINED POTENTIALS: ";
  for (long long i = 0; i < 2 * n + 6; i++) {
          cout << dist[i] << ' ';
  }
  cout << '\n';*/
  return dist[SINK] != INF;
}

void bellmanford() {
  for (long long i = 0; i < 2 * n + 6; i++)
    pot[i] = INF;
  pot[0] = 0;
  for (long long i = 0; i < 2 * n + 5; i++) {
    for (long long j = 0; j < edgelist.size(); j++) {
      if (edgelist[j]->cap > 0)
        pot[edgelist[j]->to] = min(pot[edgelist[j]->to],
                                   pot[edgelist[j]->from] + edgelist[j]->cost);
    }
  }
  /*cout << "POTENTIALS: ";
  for (long long i = 0; i < 2 * n + 6; i++) {
          cout << pot[i] << " ";
  } cout << '\n';*/
}

long long mincostmaxflow() {
  bellmanford();
  for (long long i = 0; i < 2 * n + 6; i++)
    par[i] = NULL;
  long long mincost = 0;
  long long maxflow = 0;
  while (find_aug_path()) {
    long long highestflow = INF;
    long long v = SINK;
    while (v != SOURCE) {
      highestflow = min(par[v]->cap - par[v]->flow, highestflow);
      v = par[v]->from;
    }

    v = SINK;
    while (v != SOURCE) {
      par[v]->flow += highestflow;
      edgelist[par[v]->revid]->flow -= highestflow;
      v = par[v]->from;
    }

    maxflow += highestflow;
    mincost += highestflow * (pot[SINK] + dist[SINK]);
    for (long long i = 0; i < 2 * n + 6; i++) {
      pot[i] = min(pot[i] + dist[i], INF);
    }
    for (long long i = 0; i < 2 * n + 6; i++)
      par[i] = NULL;
  }
  // assert(maxflow == n);
  return mincost;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cin >> n;
  for (long long i = 0; i < n; i++) {
    long long x, y, am;
    cin >> x >> y >> am;
    edge *v =
        new edge(SOURCE, gennode(false, i), 0, 0, am, edgelist.size() + 1);
    edge *vrev = new edge(gennode(false, i), SOURCE, 0, 0, 0, edgelist.size());
    adjlist[gennode(false, i)].push_back(vrev);
    adjlist[SOURCE].push_back(v);
    edgelist.push_back(v);
    edgelist.push_back(vrev);
    for (long long j = 0; j < 4; j++) {
      edge *totypes = new edge(gennode(false, i), type[j], 0, -(x + y), am,
                               edgelist.size() + 1);
      edge *totypesrev =
          new edge(type[j], gennode(false, i), 0, (x + y), 0, edgelist.size());
      edgelist.push_back(totypes);
      edgelist.push_back(totypesrev);
      adjlist[type[j]].push_back(totypesrev);
      adjlist[gennode(false, i)].push_back(totypes);
      x = -x;
      if (j % 2)
        y = -y;
    }
  }

  for (long long i = 0; i < n; i++) {
    long long x, y, am;
    cin >> x >> y >> am;
    edge *v = new edge(gennode(true, i), SINK, 0, 0, am, edgelist.size() + 1);
    edge *vrev = new edge(SINK, gennode(true, i), 0, 0, 0, edgelist.size());
    edgelist.push_back(v);
    edgelist.push_back(vrev);
    adjlist[gennode(true, i)].push_back(v);
    adjlist[SINK].push_back(vrev);
    y = -y;
    for (long long j = 0; j < 4; j++) {
      x = -x;
      edge *totypes = new edge(type[j], gennode(true, i), 0, -(x + y), am,
                               edgelist.size() + 1);
      edge *totypesrev =
          new edge(gennode(true, i), type[j], 0, x + y, 0, edgelist.size());
      edgelist.push_back(totypes);
      edgelist.push_back(totypesrev);
      adjlist[type[j]].push_back(totypes);
      adjlist[gennode(true, i)].push_back(totypesrev);
      if (j == 1)
        y = -y;
    }
  }
  /*for (long long i = 0; i < 2 * n + 6; i++) {
          cout << i << " : ";
          for (long long j = 0; j < adjlist[i].size(); j++) {
                  cout << adjlist[i][j]->from << ' ' << adjlist[i][j]->to << ' '
  << adjlist[i][j]->cost << ' ' << adjlist[i][j]->cap << ' ' <<
  adjlist[i][j]->revid << " | ";
          }
          cout << '\n';
  }*/
  cout << -mincostmaxflow() << '\n';
}

Fixed submission:
#include <cassert>
#include <iostream>
#include <queue>
#include <vector>
#define SOURCE 0
#define SINK 1
#define INF 1000000000000000000LL
using namespace std;
long long n;
long long type[] = {2, 3, 4, 5};
struct edge {
  long long cost, from, to, revid, flow, cap;
  edge(long long fr, long long to, long long flo, long long cost, long long cap,
       long long id)
      : from(fr), to(to), cost(cost), flow(flo), cap(cap), revid(id) {}
  bool operator<(edge *other) { return cost < other->cost; }
};

long long gennode(bool redorblue, long long ind) {
  return 6 + redorblue * n + ind;
}
vector<edge *> edgelist;
vector<edge *> adjlist[2050];
long long pot[2050];
long long dist[2050];
edge *par[2050];
priority_queue<pair<long long, edge *>, vector<pair<long long, edge *>>,
               greater<pair<long long, edge *>>>
    pq;
bool find_aug_path() {
  for (long long i = 0; i < 2 * n + 6; i++)
    dist[i] = INF;
  pq.push(make_pair(0, new edge(SOURCE, SOURCE, 0, 0, 0, 0)));
  while (!pq.empty()) {
    edge *prioredge = pq.top().second;
    long long curdist = pq.top().first;
    long long curnode = prioredge->to;
    pq.pop();
    if (dist[curnode] == INF) {
      dist[curnode] = curdist;
      par[curnode] = prioredge;
      for (long long i = 0; i < adjlist[curnode].size(); i++) {
        edge *cur = adjlist[curnode][i];
        if (cur->cap - cur->flow > 0) {
          assert(curdist + cur->cost + pot[cur->from] - pot[cur->to] >= 0);
          pq.push(make_pair(curdist + cur->cost + pot[cur->from] - pot[cur->to],
                            cur));
        }
      }
    }
  }
  /*cout << "OBTAINED POTENTIALS: ";
  for (long long i = 0; i < 2 * n + 6; i++) {
          cout << dist[i] << ' ';
  }
  cout << '\n';*/
  return dist[SINK] != INF;
}

void bellmanford() {
  for (long long i = 0; i < 2 * n + 6; i++)
    pot[i] = INF;
  pot[0] = 0;
  for (long long i = 0; i < 2 * n + 5; i++) {
    for (long long j = 0; j < edgelist.size(); j++) {
      if (edgelist[j]->cap > 0)
        pot[edgelist[j]->to] = min(pot[edgelist[j]->to],
                                   pot[edgelist[j]->from] + edgelist[j]->cost);
    }
  }
  /*cout << "POTENTIALS: ";
  for (long long i = 0; i < 2 * n + 6; i++) {
          cout << pot[i] << " ";
  } cout << '\n';*/
}

long long mincostmaxflow() {
  bellmanford();
  for (long long i = 0; i < 2 * n + 6; i++)
    par[i] = NULL;
  long long mincost = 0;
  long long maxflow = 0;
  while (find_aug_path()) {
    long long highestflow = INF;
    long long v = SINK;
    while (v != SOURCE) {
      highestflow = min(par[v]->cap - par[v]->flow, highestflow);
      v = par[v]->from;
    }

    v = SINK;
    while (v != SOURCE) {
      par[v]->flow += highestflow;
      edgelist[par[v]->revid]->flow -= highestflow;
      v = par[v]->from;
    }

    maxflow += highestflow;
    mincost += highestflow * (pot[SINK] + dist[SINK]);
    for (long long i = 0; i < 2 * n + 6; i++) {
      pot[i] = min(pot[i] + dist[i], INF);
    }
    for (long long i = 0; i < 2 * n + 6; i++)
      par[i] = NULL;
  }
  // assert(maxflow == n);
  return mincost;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cin >> n;
  for (long long i = 0; i < n; i++) {
    long long x, y, am;
    cin >> x >> y >> am;
    edge *v =
        new edge(SOURCE, gennode(false, i), 0, 0, am, edgelist.size() + 1);
    edge *vrev = new edge(gennode(false, i), SOURCE, 0, 0, 0, edgelist.size());
    adjlist[gennode(false, i)].push_back(vrev);
    adjlist[SOURCE].push_back(v);
    edgelist.push_back(v);
    edgelist.push_back(vrev);
    for (long long j = 0; j < 4; j++) {
      edge *totypes = new edge(gennode(false, i), type[j], 0, -(x + y), am,
                               edgelist.size() + 1);
      edge *totypesrev =
          new edge(type[j], gennode(false, i), 0, (x + y), 0, edgelist.size());
      edgelist.push_back(totypes);
      edgelist.push_back(totypesrev);
      adjlist[type[j]].push_back(totypesrev);
      adjlist[gennode(false, i)].push_back(totypes);
      x = -x;
      if (j % 2)
        y = -y;
    }
  }

  for (long long i = 0; i < n; i++) {
    long long x, y, am;
    cin >> x >> y >> am;
    edge *v = new edge(gennode(true, i), SINK, 0, 0, am, edgelist.size() + 1);
    edge *vrev = new edge(SINK, gennode(true, i), 0, 0, 0, edgelist.size());
    edgelist.push_back(v);
    edgelist.push_back(vrev);
    adjlist[gennode(true, i)].push_back(v);
    adjlist[SINK].push_back(vrev);
    y = -y;
    for (long long j = 0; j < 4; j++) {
      x = -x;
      edge *totypes = new edge(type[j], gennode(true, i), 0, -(x + y), am,
                               edgelist.size() + 1);
      edge *totypesrev =
          new edge(gennode(true, i), type[j], 0, x + y, 0, edgelist.size());
      edgelist.push_back(totypes);
      edgelist.push_back(totypesrev);
      adjlist[type[j]].push_back(totypes);
      adjlist[gennode(true, i)].push_back(totypesrev);
      if (j == 1)
        y = -y;
    }
  }
  /*for (long long i = 0; i < 2 * n + 6; i++) {
          cout << i << " : ";
          for (long long j = 0; j < adjlist[i].size(); j++) {
                  cout << adjlist[i][j]->from << ' ' << adjlist[i][j]->to << ' '
  << adjlist[i][j]->cost << ' ' << adjlist[i][j]->cap << ' ' <<
  adjlist[i][j]->revid << " | ";
          }
          cout << '\n';
  }*/
  cout << -mincostmaxflow() << '\n';
}