Problem p01928 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <iostream>
#include <vector>
#define llint long long
#define inf 1e18

using namespace std;

struct Edge {
  llint to, cost;
  Edge() {}
  Edge(llint a, llint b) { to = a, cost = b; }
};

llint N;
llint L[105][3];
vector<Edge> g[105];

llint volume(llint x) {
  llint ret = 1;
  for (llint i = 0; i < 3; i++)
    ret *= L[x][i];
  return ret;
}

bool compare(llint x, llint y) {
  for (llint i = 0; i < 3; i++) {
    if (L[x][i] <= L[y][i])
      return false;
  }
  return true;
}

struct edge {
  llint to, cap, cost, rev;
  edge() {}
  edge(llint a, llint b, llint c, llint d) {
    to = a, cap = b, cost = c, rev = d;
  }
};

llint S, T;
vector<edge> G[205];
llint dist[205];
llint prevv[205], preve[205];

void BellmanFord() {
  for (llint i = 0; i <= T; i++)
    dist[i] = inf;
  dist[S] = 0, prevv[S] = -1;

  bool update = true;
  while (update) {
    update = false;
    for (llint i = 0; i <= T; i++) {
      for (llint j = 0; j < G[i].size(); j++) {
        if (G[i][j].cap == 0)
          continue;
        if (dist[G[i][j].to] > dist[i] + G[i][j].cost) {
          dist[G[i][j].to] = dist[i] + G[i][j].cost;
          prevv[G[i][j].to] = i;
          preve[G[i][j].to] = j;
          update = true;
        }
      }
    }
  }
}

void add_edge(llint from, llint to, llint cap, llint cost) {
  G[from].push_back(edge(to, cap, cost, G[to].size()));
  G[to].push_back(edge(from, 0, -cost, G[from].size() - 1));
}

int main(void) {
  while (1) {
    cin >> N;
    if (N == 0)
      break;
    for (llint i = 0; i < N; i++) {
      for (llint j = 0; j < 3; j++) {
        cin >> L[i][j];
      }
      sort(L[i], L[i] + 3);
    }

    for (llint i = 0; i < N; i++)
      g[i].clear();
    for (llint i = 0; i < N; i++) {
      for (llint j = 0; j < N; j++) {
        if (compare(i, j)) {
          g[i].push_back(Edge(j, volume(j)));
        }
      }
    }

    S = 2 * N + 1, T = 2 * N + 2;
    for (llint i = 0; i <= T; i++)
      G[i].clear();
    for (llint i = 0; i < N; i++) {
      for (llint j = 0; j < g[i].size(); j++) {
        add_edge(i, N + g[j][j].to, inf, -g[i][j].cost);
      }
    }
    for (llint i = 0; i < N; i++) {
      add_edge(S, i, 1, 0);
      add_edge(i + N, T, 1, 0);
    }

    llint ans = 0;
    while (1) {
      BellmanFord();
      if (dist[T] >= inf / 2)
        break;

      llint p = T, flow = N;
      while (prevv[p] != -1) {
        flow = min(flow, G[prevv[p]][preve[p]].cap);
        p = prevv[p];
      }

      p = T;
      while (prevv[p] != -1) {
        G[prevv[p]][preve[p]].cap -= flow;
        G[p][G[prevv[p]][preve[p]].rev].cap += flow;
        p = prevv[p];
      }
      ans += dist[T] * flow;
    }

    llint sum = 0;
    for (llint i = 0; i < N; i++)
      sum += volume(i);
    ans = sum + ans;
    cout << ans << endl;
  }

  return 0;
}


Fixed submission:
#include <algorithm>
#include <iostream>
#include <vector>
#define llint long long
#define inf 1e18

using namespace std;

struct Edge {
  llint to, cost;
  Edge() {}
  Edge(llint a, llint b) { to = a, cost = b; }
};

llint N;
llint L[105][3];
vector<Edge> g[105];

llint volume(llint x) {
  llint ret = 1;
  for (llint i = 0; i < 3; i++)
    ret *= L[x][i];
  return ret;
}

bool compare(llint x, llint y) {
  for (llint i = 0; i < 3; i++) {
    if (L[x][i] <= L[y][i])
      return false;
  }
  return true;
}

struct edge {
  llint to, cap, cost, rev;
  edge() {}
  edge(llint a, llint b, llint c, llint d) {
    to = a, cap = b, cost = c, rev = d;
  }
};

llint S, T;
vector<edge> G[205];
llint dist[205];
llint prevv[205], preve[205];

void BellmanFord() {
  for (llint i = 0; i <= T; i++)
    dist[i] = inf;
  dist[S] = 0, prevv[S] = -1;

  bool update = true;
  while (update) {
    update = false;
    for (llint i = 0; i <= T; i++) {
      for (llint j = 0; j < G[i].size(); j++) {
        if (G[i][j].cap == 0)
          continue;
        if (dist[G[i][j].to] > dist[i] + G[i][j].cost) {
          dist[G[i][j].to] = dist[i] + G[i][j].cost;
          prevv[G[i][j].to] = i;
          preve[G[i][j].to] = j;
          update = true;
        }
      }
    }
  }
}

void add_edge(llint from, llint to, llint cap, llint cost) {
  G[from].push_back(edge(to, cap, cost, G[to].size()));
  G[to].push_back(edge(from, 0, -cost, G[from].size() - 1));
}

int main(void) {
  while (1) {
    cin >> N;
    if (N == 0)
      break;
    for (llint i = 0; i < N; i++) {
      for (llint j = 0; j < 3; j++) {
        cin >> L[i][j];
      }
      sort(L[i], L[i] + 3);
    }

    for (llint i = 0; i < N; i++)
      g[i].clear();
    for (llint i = 0; i < N; i++) {
      for (llint j = 0; j < N; j++) {
        if (compare(i, j)) {
          g[i].push_back(Edge(j, volume(j)));
        }
      }
    }

    S = 2 * N + 1, T = 2 * N + 2;
    for (llint i = 0; i <= T; i++)
      G[i].clear();
    for (llint i = 0; i < N; i++) {
      for (llint j = 0; j < g[i].size(); j++) {
        add_edge(i, N + g[i][j].to, inf, -g[i][j].cost);
      }
    }
    for (llint i = 0; i < N; i++) {
      add_edge(S, i, 1, 0);
      add_edge(i + N, T, 1, 0);
    }

    llint ans = 0;
    while (1) {
      BellmanFord();
      if (dist[T] >= inf / 2)
        break;

      llint p = T, flow = N;
      while (prevv[p] != -1) {
        flow = min(flow, G[prevv[p]][preve[p]].cap);
        p = prevv[p];
      }

      p = T;
      while (prevv[p] != -1) {
        G[prevv[p]][preve[p]].cap -= flow;
        G[p][G[prevv[p]][preve[p]].rev].cap += flow;
        p = prevv[p];
      }
      ans += dist[T] * flow;
    }

    llint sum = 0;
    for (llint i = 0; i < N; i++)
      sum += volume(i);
    ans = sum + ans;
    cout << ans << endl;
  }

  return 0;
}