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

#include <algorithm>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <utility>
#include <vector>

using namespace std;

typedef pair<int, int> P;

struct edge {
  int to, cap, cost, rev;
};

const int N = 99602;
const int INF = 1 << 29;
int V;
vector<vector<edge>> G;
int h[N];
int dist[N];
int prevv[N], preve[N];

void set_id(map<int, int> &m) {
  int x = 0;
  for (auto &e : m) {
    e.second = x++;
  }
}

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

// pair<int,int> min_cost_flow(int s,int t,int g){
//   int res=0;
//   fill(h,h+V,0);
//   int f=0;
//   while(f<g){
//     priority_queue<P,vector<P>,greater<P> > que;
//     fill(dist,dist+V,INF);
//     dist[s]=0;
//     que.push({0,s});
//     while(!que.empty()){
//       P p=que.top();
//       que.pop();
//       int v=p.second;
//       if(dist[v]<p.first)continue;
//       for(int i=0;i<G[v].size();i++){
// 	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;
// 	  que.push({dist[e.to],e.to});
// 	}
//       }
//     }
//     if(dist[t]>=INF){
//       return {f,res};
//     }
//     for(int v=0;v<V;v++){
//       h[v]+=dist[v];
//     }
//     f++;
//     res+=h[t];
//     for(int v=t;v!=s;v=prevv[v]){
//       edge &e=G[prevv[v]][preve[v]];
//       e.cap--;
//       G[v][e.rev].cap++;
//     }
//   }
//   return {f,res};
// }

pair<int, int> min_cost_flow(int s, int t, int f) {
  int res = 0;
  const int INF = 1 << 29;
  fill(h, h + V, INF);
  h[s] = 0;
  for (;;) {
    bool u = false;
    for (int i = 0; i < V; i++) {
      for (auto f : G[i]) {
        if (f.cap) {
          int nd = h[i] + f.cost;
          if (nd < h[f.to]) {
            h[f.to] = nd;
            u = true;
          }
        }
      }
    }
    if (!u)
      break;
  }
  int g = 0;
  while (g < f) {
    priority_queue<P, vector<P>, greater<P>> que;
    fill(dist, dist + V, INF);
    dist[s] = 0;
    que.push({0, s});
    while (!que.empty()) {
      P p = que.top();
      que.pop();
      int v = p.second;
      if (dist[v] < p.first)
        continue;
      for (int i = 0; i < G[v].size(); i++) {
        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;
          que.push({dist[e.to], e.to});
        }
      }
    }
    if (dist[t] == INF)
      return {g, res};
    for (int v = 0; v < V; v++) {
      h[v] += dist[v];
    }
    int d = INF;
    for (int v = t; v != s; v = prevv[v]) {
      d = min(d, G[prevv[v]][preve[v]].cap);
    }
    g += d;
    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 {g, res};
}

int main() {
  for (int n; cin >> n, n;) {
    map<int, int> in[100], out[100];
    int o[101] = {2};
    int m[100];
    int x[100][20], y[100][20], c[100][20];
    G = vector<vector<edge>>(N);
    for (int i = 0; i < n - 1; i++) {
      cin >> m[i];
      for (int j = 0; j < m[i]; j++) {
        cin >> x[i][j] >> y[i][j] >> c[i][j];
        in[i][x[i][j]];
        out[i][y[i][j]];
      }
      set_id(in[i]);
      set_id(out[i]);
      for (int j = 0; j < m[i]; j++) {
        add_edge(o[i] + in[i][x[i][j]], o[i] + in[i].size() + out[i][y[i][j]],
                 c[i][j]);
      }
      if (i) {
        for (auto e : out[i - 1]) {
          for (auto f : in[i]) {
            if (e.first <= f.first) {
              add_edge(o[i - 1] + in[i - 1].size() + out[i - 1].size() +
                           e.second,
                       o[i] + f.second);
            }
          }
        }
      }
      for (auto e : out[i]) {
        add_edge(o[i] + in[i].size() + e.second,
                 o[i] + in[i].size() + out[i].size() + e.second, 0, 1);
      }
      o[i + 1] = o[i] + in[i].size() + 2 * out[i].size();
    }
    for (auto e : in[0]) {
      add_edge(0, 2 + e.second);
    }
    for (auto f : out[n - 2]) {
      add_edge(o[n - 2] + in[n - 2].size() + out[n - 2].size() + f.second, 1);
    }
    V = o[n - 1];
    int g;
    cin >> g;
    auto r = min_cost_flow(0, 1, g);
    cout << r.first << ' ' << r.second << endl;
  }
}


Error: 0

Fixed submission:

#include <algorithm>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <utility>
#include <vector>

using namespace std;

typedef pair<int, int> P;

struct edge {
  int to, cap, cost, rev;
};

const int N = 602;
const int INF = 1 << 29;
int V;
vector<vector<edge>> G;
int h[N];
int dist[N];
int prevv[N], preve[N];

void set_id(map<int, int> &m) {
  int x = 0;
  for (auto &e : m) {
    e.second = x++;
  }
}

void add_edge(int from, int to, int cost = 0, int cap = INF) {
  if (from < 0 || G.size() <= from)
    for (;;)
      ;

  G[from].push_back({to, cap, cost, (int)G[to].size()});
  G[to].push_back({from, 0, -cost, (int)G[from].size() - 1});
}

// pair<int,int> min_cost_flow(int s,int t,int g){
//   int res=0;
//   fill(h,h+V,0);
//   int f=0;
//   while(f<g){
//     priority_queue<P,vector<P>,greater<P> > que;
//     fill(dist,dist+V,INF);
//     dist[s]=0;
//     que.push({0,s});
//     while(!que.empty()){
//       P p=que.top();
//       que.pop();
//       int v=p.second;
//       if(dist[v]<p.first)continue;
//       for(int i=0;i<G[v].size();i++){
// 	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;
// 	  que.push({dist[e.to],e.to});
// 	}
//       }
//     }
//     if(dist[t]>=INF){
//       return {f,res};
//     }
//     for(int v=0;v<V;v++){
//       h[v]+=dist[v];
//     }
//     f++;
//     res+=h[t];
//     for(int v=t;v!=s;v=prevv[v]){
//       edge &e=G[prevv[v]][preve[v]];
//       e.cap--;
//       G[v][e.rev].cap++;
//     }
//   }
//   return {f,res};
// }

pair<int, int> min_cost_flow(int s, int t, int f) {
  int res = 0;
  const int INF = 1 << 29;
  fill(h, h + V, INF);
  h[s] = 0;
  for (;;) {
    bool u = false;
    for (int i = 0; i < V; i++) {
      for (auto f : G[i]) {
        if (f.cap) {
          int nd = h[i] + f.cost;
          if (nd < h[f.to]) {
            h[f.to] = nd;
            u = true;
          }
        }
      }
    }
    if (!u)
      break;
  }
  int g = 0;
  while (g < f) {
    priority_queue<P, vector<P>, greater<P>> que;
    fill(dist, dist + V, INF);
    dist[s] = 0;
    que.push({0, s});
    while (!que.empty()) {
      P p = que.top();
      que.pop();
      int v = p.second;
      if (dist[v] < p.first)
        continue;
      for (int i = 0; i < G[v].size(); i++) {
        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;
          que.push({dist[e.to], e.to});
        }
      }
    }
    if (dist[t] == INF)
      return {g, res};
    for (int v = 0; v < V; v++) {
      h[v] += dist[v];
    }
    int d = INF;
    for (int v = t; v != s; v = prevv[v]) {
      d = min(d, G[prevv[v]][preve[v]].cap);
    }
    g += d;
    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 {g, res};
}

int main() {
  for (int n; cin >> n, n;) {
    map<int, int> in[100], out[100];
    int o[101] = {2};
    int m[100];
    int x[100][20], y[100][20], c[100][20];
    G = vector<vector<edge>>(N);
    for (int i = 0; i < n - 1; i++) {
      cin >> m[i];
      for (int j = 0; j < m[i]; j++) {
        cin >> x[i][j] >> y[i][j] >> c[i][j];
        in[i][x[i][j]];
        out[i][y[i][j]];
      }
      set_id(in[i]);
      set_id(out[i]);
      for (int j = 0; j < m[i]; j++) {
        add_edge(o[i] + in[i][x[i][j]], o[i] + in[i].size() + out[i][y[i][j]],
                 c[i][j]);
      }
      if (i) {
        for (auto e : out[i - 1]) {
          for (auto f : in[i]) {
            if (e.first <= f.first) {
              add_edge(o[i - 1] + in[i - 1].size() + out[i - 1].size() +
                           e.second,
                       o[i] + f.second);
            }
          }
        }
      }
      for (auto e : out[i]) {
        add_edge(o[i] + in[i].size() + e.second,
                 o[i] + in[i].size() + out[i].size() + e.second, 0, 1);
      }
      o[i + 1] = o[i] + in[i].size() + 2 * out[i].size();
    }
    for (auto e : in[0]) {
      add_edge(0, 2 + e.second);
    }
    for (auto f : out[n - 2]) {
      add_edge(o[n - 2] + in[n - 2].size() + out[n - 2].size() + f.second, 1);
    }
    V = o[n - 1];
    int g;
    cin >> g;
    auto r = min_cost_flow(0, 1, g);
    cout << r.first << ' ' << r.second << endl;
  }
}