Problem p03020 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn = 2000, maxm = 20005;
const ll inf = 1e11;

struct Edge {
  Edge() {}
  Edge(int a, int b, ll c, int d) {
    v = a;
    f = b;
    w = c;
    nxt = d;
  }
  int v, f, w, nxt;
};

int n, lmt;
int g[maxn + 10];
Edge e[maxm + 10];
int nume = 1;
int src, sink;

void addedge(int u, int v, int c, ll w) {
  e[++nume] = Edge(v, c, w, g[u]);
  g[u] = nume;
  e[++nume] = Edge(u, 0, -w, g[v]);
  g[v] = nume;
}

queue<int> que;
bool inq[maxn + 10];
ll dist[maxn + 10];
int prv[maxn + 10], pree[maxn + 10];

bool findpath() {
  while (!que.empty())
    que.pop();
  que.push(src);
  // memset(dist,63,sizeof dist);
  for (int i = 0; i < maxn; ++i)
    dist[i] = inf;
  dist[src] = 0;
  inq[src] = true;
  while (!que.empty()) {
    int u = que.front();
    que.pop();
    for (int i = g[u]; i; i = e[i].nxt) {
      if (e[i].f > 0 && dist[u] + e[i].w < dist[e[i].v]) {
        dist[e[i].v] = dist[u] + e[i].w;
        prv[e[i].v] = u;
        pree[e[i].v] = i;
        if (!inq[e[i].v]) {
          inq[e[i].v] = true;
          que.push(e[i].v);
        }
      }
    }
    inq[u] = false;
  }
  if (dist[sink] < inf)
    return true;
  else
    return false;
}

ll augment() {
  int u = sink;
  ll delta = inf;
  while (u != src) {
    if (e[pree[u]].f < delta)
      delta = e[pree[u]].f;
    u = prv[u];
  }
  u = sink;
  while (u != src) {
    e[pree[u]].f -= delta;
    e[pree[u] ^ 1].f += delta;
    u = prv[u];
  }
  return dist[sink] * delta;
}

ll mincostflow() {
  ll cur = 0, ans = 0;
  while (findpath()) {
    cur += augment();
    if (cur < ans)
      ans = cur;
  }
  return ans;
}

int main() {
  scanf("%d", &n);
  src = 2 * n + 1, sink = 2 * n + 2;
  for (int i = 1; i <= n; ++i) {
    int x, y, c;
    scanf("%d%d%d", &x, &y, &c);
    addedge(2 * n + 1, i, c, 0);
    addedge(i, 2 * n + 3, c, x + y);
    addedge(i, 2 * n + 4, c, x - y);
    addedge(i, 2 * n + 5, c, -x + y);
    addedge(i, 2 * n + 6, c, -x - y);
  }
  for (int i = 1; i <= n; ++i) {
    int x, y, c;
    scanf("%d%d%d", &x, &y, &c);
    addedge(n + i, 2 * n + 2, c, 0);
    addedge(2 * n + 3, n + i, c, -x - y);
    addedge(2 * n + 4, n + i, c, -x + y);
    addedge(2 * n + 5, n + i, c, x - y);
    addedge(2 * n + 6, n + i, c, x + y);
  }

  ll res = mincostflow();
  printf("%lld", -res);
  return 0;
}


Fixed submission:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn = 2000, maxm = 20005;
const ll inf = 1e11;

struct Edge {
  Edge() {}
  Edge(int a, int b, ll c, int d) {
    v = a;
    f = b;
    w = c;
    nxt = d;
  }
  int v, f, w, nxt;
};

int n, lmt;
int g[maxn + 10];
Edge e[maxm + 10];
int nume = 1;
int src, sink;

void addedge(int u, int v, int c, ll w) {
  e[++nume] = Edge(v, c, w, g[u]);
  g[u] = nume;
  e[++nume] = Edge(u, 0, -w, g[v]);
  g[v] = nume;
}

queue<int> que;
bool inq[maxn + 10];
ll dist[maxn + 10];
int prv[maxn + 10], pree[maxn + 10];

bool findpath() {
  while (!que.empty())
    que.pop();
  que.push(src);
  memset(dist, 63, sizeof dist);
  // for(int i = 0;i < maxn; ++i) dist[i] = inf;
  dist[src] = 0;
  inq[src] = true;
  while (!que.empty()) {
    int u = que.front();
    que.pop();
    for (int i = g[u]; i; i = e[i].nxt) {
      if (e[i].f > 0 && dist[u] + e[i].w < dist[e[i].v]) {
        dist[e[i].v] = dist[u] + e[i].w;
        prv[e[i].v] = u;
        pree[e[i].v] = i;
        if (!inq[e[i].v]) {
          inq[e[i].v] = true;
          que.push(e[i].v);
        }
      }
    }
    inq[u] = false;
  }
  if (dist[sink] < inf)
    return true;
  else
    return false;
}

ll augment() {
  int u = sink;
  ll delta = inf;
  while (u != src) {
    if (e[pree[u]].f < delta)
      delta = e[pree[u]].f;
    u = prv[u];
  }
  u = sink;
  while (u != src) {
    e[pree[u]].f -= delta;
    e[pree[u] ^ 1].f += delta;
    u = prv[u];
  }
  return dist[sink] * delta;
}

ll mincostflow() {
  ll cur = 0, ans = 0;
  while (findpath()) {
    cur += augment();
    if (cur < ans)
      ans = cur;
  }
  return ans;
}

int main() {
  scanf("%d", &n);
  src = 2 * n + 1, sink = 2 * n + 2;
  for (int i = 1; i <= n; ++i) {
    int x, y, c;
    scanf("%d%d%d", &x, &y, &c);
    addedge(2 * n + 1, i, c, 0);
    addedge(i, 2 * n + 3, c, x + y);
    addedge(i, 2 * n + 4, c, x - y);
    addedge(i, 2 * n + 5, c, -x + y);
    addedge(i, 2 * n + 6, c, -x - y);
  }
  for (int i = 1; i <= n; ++i) {
    int x, y, c;
    scanf("%d%d%d", &x, &y, &c);
    addedge(n + i, 2 * n + 2, c, 0);
    addedge(2 * n + 3, n + i, c, -x - y);
    addedge(2 * n + 4, n + i, c, -x + y);
    addedge(2 * n + 5, n + i, c, x - y);
    addedge(2 * n + 6, n + i, c, x + y);
  }

  ll res = mincostflow();
  printf("%lld", -res);
  return 0;
}