Problem p00673 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 29)
#define MAX_V 10000
using namespace std;
typedef pair<int, int> ii;
typedef pair<ii, char> iic;
typedef pair<ii, ii> ii2;

// library start
struct edge {
  int to, cap, cost, rev;
  edge(int to = -inf, int cap = -inf, int cost = -inf, int rev = -inf)
      : to(to), cap(cap), cost(cost), rev(rev) {}
};
int V;
vector<edge> G[MAX_V];
int h[MAX_V];
int dist[MAX_V];
int prevv[MAX_V], preve[MAX_V];

void add_edge(int from, int to, int cap, int 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 min_cost_flow(int s, int t, int f) {
  int res = 0;
  rep(i, MAX_V) h[i] = 0;
  while (f > 0) {
    priority_queue<ii, vector<ii>, greater<ii>> Q;
    rep(i, MAX_V) dist[i] = inf;
    dist[s] = 0;
    Q.push(ii(0, s));
    while (!Q.empty()) {
      ii p = Q.top();
      Q.pop();
      int v = p.second;
      if (dist[v] < p.first)
        continue;
      rep(i, G[v].size()) {
        edge &e = G[v][i];
        if (e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
          dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
          prevv[e.to] = v;
          preve[e.to] = i;
          Q.push(ii(dist[e.to], e.to));
        }
      }
    }

    // cout << "dist[" << t << "] = " << dist[t] << endl;
    // if(dist[t] == inf)return -1;
    if (dist[t] == inf)
      break;
    rep(v, MAX_V) h[v] += dist[v];

    int d = f;
    for (int v = t; v != s; v = prevv[v]) {
      d = min(d, G[prevv[v]][preve[v]].cap);
    }
    f -= d;
    // cout << "d = "<< d << endl;
    res += d * h[t];
    for (int v = t; v != s; v = prevv[v]) {
      edge &e = G[prevv[v]][preve[v]];
      e.cap -= d;
      G[v][e.rev].cap += d;
    }
  }
  return res;
}

// library end

int n, g, index, last, last2;
map<iic, int> table; // table[ii(ノード番号,時刻)] = index

int getIndex(int node, int tm, char c) {
  if (table.find(iic(ii(node, tm), c)) != table.end())
    return table[iic(ii(node, tm), c)];
  table[iic(ii(node, tm), c)] = index++, ++V;
  return index - 1;
}

void init() {
  rep(i, MAX_V) G[i].clear();
  V = 0;
  index = 0;
  table.clear();
}

int main() {
  while (cin >> n, n) {
    init();
    table[iic(ii(0, 0), '0')] = index++, ++V;
    last = MAX_V - 3;
    last2 = last + 1;

    vector<ii2> input;
    vector<int> cost;
    set<int> station[n + 1][2]; // 0->到着、1->出発

    REP(i, 1, n) {
      int m;
      cin >> m;
      rep(_, m) {
        int x, y, c;
        cin >> x >> y >> c;
        cost.push_back(c);
        input.push_back(ii2(ii(i, x), ii(i + 1, y)));
        station[i][1].insert(x);
        station[i + 1][0].insert(y);
        station[i + 1][1].insert(y);
      }
    }

    REP(i, 1, n + 1) {
      for (set<int>::iterator it = station[i][0].begin();
           it != station[i][0].end(); it++) {
        getIndex(i, *it, '0');
        // cout << "到着 node = " << i << " time = " << *it << " is " <<
        // getIndex(i,*it,0) << endl;
      }
      for (set<int>::iterator it = station[i][1].begin();
           it != station[i][1].end(); it++) {
        getIndex(i, *it, '1');
        // cout << "出発 node = " << i << " time = " << *it << " is " <<
        // getIndex(i,*it,1) << endl;
      }
    }

    rep(i, input.size()) {
      ii from, to;
      from = input[i].first;
      to = input[i].second;
      add_edge(getIndex(from.first, from.second, '1'),
               getIndex(to.first, to.second, '0'), 1, cost[i]);
    }

    REP(i, 2, n + 1) {
      for (set<int>::iterator it2 = station[i][0].begin();
           it2 != station[i][0].end(); it2++) {
        int id = getIndex(i, *it2, 'x');
        add_edge(getIndex(i, *it2, '0'), id, 1, 0);
        for (set<int>::iterator it = station[i][1].begin();
             it != station[i][1].end(); it++) {
          if (*it >= *it2) {
            add_edge(id, getIndex(i, *it, '1'), 1, 0);
          }
        }
      }
    }

    for (set<int>::iterator it = station[1][1].begin();
         it != station[1][1].end(); it++) {
      add_edge(0, getIndex(1, *it, '1'), inf, 0);
    }

    for (set<int>::iterator it = station[n][1].begin();
         it != station[n][1].end(); it++) {
      add_edge(getIndex(n, *it, '1'), last, 1, 0);
    }

    cin >> g;
    add_edge(last, last2, g, 0);

    /*
    cout << "V = " << V << endl;
    rep(i,MAX_V)
      {
        if(G[i].empty())continue;
        cout << "from " << i << endl;
        rep(j,G[i].size())
          {
            edge e = G[i][j];
            cout << "(to,cap,cost,rev) = (" << e.to << "," << e.cap << "," <<
    e.cost << "," << e.rev << ")" << endl;
          }
        cout << "----" << endl;
      }
    cout << endl;
    */

    int ans = min_cost_flow(0, last2, inf);
    if (g == G[last][G[last].size() - 1].cap)
      cout << "0 0" << endl;
    else
      cout << g - G[last][G[last].size() - 1].cap << " " << ans << endl;
  }
  return 0;
}

Error: WA

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 29)
#define MAX_V (100 * 20 + 10)
using namespace std;
typedef pair<int, int> ii;
typedef pair<ii, bool> iib;
typedef pair<ii, ii> ii2;

// library start
struct edge {
  int to, cap, cost, rev;
  edge(int to = -inf, int cap = -inf, int cost = -inf, int rev = -inf)
      : to(to), cap(cap), cost(cost), rev(rev) {}
};
int V;
vector<edge> G[MAX_V];
int h[MAX_V];
int dist[MAX_V];
int prevv[MAX_V], preve[MAX_V];

void add_edge(int from, int to, int cap, int 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 min_cost_flow(int s, int t, int f) {
  int res = 0;
  rep(i, MAX_V) h[i] = 0;
  while (f > 0) {
    priority_queue<ii, vector<ii>, greater<ii>> Q;
    rep(i, MAX_V) dist[i] = inf;
    dist[s] = 0;
    Q.push(ii(0, s));
    while (!Q.empty()) {
      ii p = Q.top();
      Q.pop();
      int v = p.second;
      if (dist[v] < p.first)
        continue;
      rep(i, G[v].size()) {
        edge &e = G[v][i];
        if (e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
          dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
          prevv[e.to] = v;
          preve[e.to] = i;
          Q.push(ii(dist[e.to], e.to));
        }
      }
    }

    // cout << "dist[" << t << "] = " << dist[t] << endl;
    // if(dist[t] == inf)return -1;
    if (dist[t] == inf)
      break;
    rep(v, MAX_V) h[v] += dist[v];

    int d = f;
    for (int v = t; v != s; v = prevv[v]) {
      d = min(d, G[prevv[v]][preve[v]].cap);
    }
    f -= d;
    // cout << "d = "<< d << endl;
    res += d * h[t];
    for (int v = t; v != s; v = prevv[v]) {
      edge &e = G[prevv[v]][preve[v]];
      e.cap -= d;
      G[v][e.rev].cap += d;
    }
  }
  return res;
}

// library end

int n, g, index, last, last2;
map<iib, int> table; // table[ii(ノード番号,時刻)] = index

int getIndex(int node, int tm, bool fl) {
  if (table.find(iib(ii(node, tm), fl)) != table.end())
    return table[iib(ii(node, tm), fl)];
  table[iib(ii(node, tm), fl)] = index++, ++V;
  return index - 1;
}

void init() {
  rep(i, MAX_V) G[i].clear();
  V = 0;
  index = 0;
  table.clear();
}

int main() {
  while (cin >> n, n) {
    init();
    table[iib(ii(0, 0), 0)] = index++, ++V;
    last = MAX_V - 3;
    last2 = last + 1;

    vector<ii2> input;
    vector<int> cost;
    set<int> station[n + 1][2]; // 0->到着、1->出発

    REP(i, 1, n) {
      int m;
      cin >> m;
      rep(_, m) {
        int x, y, c;
        cin >> x >> y >> c;
        cost.push_back(c);
        input.push_back(ii2(ii(i, x), ii(i + 1, y)));
        station[i][1].insert(x);
        station[i + 1][0].insert(y);
        station[i + 1][1].insert(y);
      }
    }

    REP(i, 1, n + 1) {
      for (set<int>::iterator it = station[i][0].begin();
           it != station[i][0].end(); it++) {
        getIndex(i, *it, 0);
        // cout << "到着 node = " << i << " time = " << *it << " is " <<
        // getIndex(i,*it,0) << endl;
      }
      for (set<int>::iterator it = station[i][1].begin();
           it != station[i][1].end(); it++) {
        getIndex(i, *it, 1);
        // cout << "出発 node = " << i << " time = " << *it << " is " <<
        // getIndex(i,*it,1) << endl;
      }
    }

    rep(i, input.size()) {
      ii from, to;
      from = input[i].first;
      to = input[i].second;
      add_edge(getIndex(from.first, from.second, 1),
               getIndex(to.first, to.second, 0), 1, cost[i]);
      for (set<int>::iterator it = station[to.first][1].begin();
           it != station[to.first][1].end(); it++) {
        if (*it >= to.second) {
          add_edge(getIndex(to.first, to.second, 0), getIndex(to.first, *it, 1),
                   1, 0);
        }
      }
    }

    for (set<int>::iterator it = station[1][1].begin();
         it != station[1][1].end(); it++) {
      add_edge(0, getIndex(1, *it, 1), inf, 0);
    }

    for (set<int>::iterator it = station[n][1].begin();
         it != station[n][1].end(); it++) {
      add_edge(getIndex(n, *it, 1), last, 1, 0);
    }

    cin >> g;
    add_edge(last, last2, g, 0);

    /*
    cout << "V = " << V << endl;
    rep(i,MAX_V)
      {
        if(G[i].empty())continue;
        cout << "from " << i << endl;
        rep(j,G[i].size())
          {
            edge e = G[i][j];
            cout << "(to,cap,cost,rev) = (" << e.to << "," << e.cap << "," <<
    e.cost << "," << e.rev << ")" << endl;
          }
        cout << "----" << endl;
      }
    cout << endl;
    */
    if (g == G[last][G[last].size() - 1].cap)
      cout << "0 0 " << endl;
    else
      cout << g - G[last][G[last].size() - 1].cap << " "
           << min_cost_flow(0, last2, inf) << endl;
  }
  return 0;
}