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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;
#define repeat(i, n) for (int i = 0; i < (n); ++i)

template <typename T> class ford_fulkerson {
public:
  struct edge_t {
    int to;
    T cap;
    int rev;
  };
  static T infinity;

  ford_fulkerson() {}
  ford_fulkerson(int n) : graph(n) {}

  vector<vector<edge_t>> graph; // adjacency list

  int add_vertex() {
    graph.push_back(vector<edge_t>());
    return graph.size() - 1;
  }

  void add_edge(int from, T to, int cap) {
    graph[from].push_back((edge_t){to, cap, (int)graph[to].size()});
    graph[to].push_back((edge_t){from, 0, (int)graph[from].size() - 1});
  }

  vector<bool> used;

  T run_destructive(int s, int t) {
    T flow = 0;
    used.resize(graph.size());
    while (true) {
      fill(used.begin(), used.end(), false);
      T f = dfs(s, t, infinity);
      if (f == 0)
        return flow;
      flow += f;
    }
  }

  // search augmenting pathes from `v' to `t', returns the volume of water `f'
  T dfs(int v, int t, T f) {
    if (v == t)
      return f; // base case
    used[v] = true;
    repeat(i, (int)graph[v].size()) { // for each adjacent nodes which are not
                                      // used and able to flow
      edge_t &e = graph[v][i];
      const int w = e.to;
      if (not used[w] and 0 < e.cap) {
        T d = dfs(w, t, min(f, e.cap)); // v -> w ->> t
        if (0 < d) {                    // let flow and make reverse capacity
          e.cap -= d;
          graph[w][e.rev].cap += d;
          return d;
        }
      }
    }
    return 0; // path not found
  }
};
template <> int ford_fulkerson<int>::infinity = 1e9;
template <> long long ford_fulkerson<long long>::infinity = 1e18;
template <> double ford_fulkerson<double>::infinity = 1 / (double)0;
int sq(int x) { return x * x; }
double hypot(int x, int y) { return sqrt(sq(x) + sq(y)); }
double distance(int ax, int ay, int bx, int by) {
  return hypot(ax - bx, ay - by);
}
template <class T, class S> double distance(const T &a, const S &b) {
  return hypot(a.x - b.x, a.y - b.y);
}

#define MAX_N 100
#define MAX_M 100
struct troop_t {
  int x, y, v;
};
struct base_t {
  int x, y;
};
double time(const troop_t &t, const base_t &b) {
  return distance(t, b) / (double)t.v;
}
struct path_t {
  int n, m;
  double t;
};
bool operator<(const path_t &a, const path_t &b) {
  return make_pair(a.t, make_pair(a.n, a.m)) <
         make_pair(b.t, make_pair(b.n, b.m));
}

int main() {
  while (true) {
    int N, M;
    cin >> N >> M;
    if (N == 0 or M == 0)
      break;
    static troop_t T[MAX_N];
    repeat(n, N) cin >> T[n].x >> T[n].y >> T[n].v;
    static base_t B[MAX_M];
    repeat(m, M) cin >> B[m].x >> B[m].y;

    static path_t p[MAX_N * MAX_M];
    repeat(n, N) repeat(m, M) p[M * n + m] = (path_t){n, m, time(T[n], B[m])};
    sort(p, p + N * M);

    int low = M, high = N * M; // the answer is in [low,high]
    while (low < high) {
      int mid = (low + high) / 2;
      ford_fulkerson<int> mf(1 + N + M + 1);
      repeat(n, N) mf.add_edge(0, 1 + n, 1);
      repeat(i, mid) mf.add_edge(1 + p[i].n, 1 + N + p[i].m, 1);
      repeat(m, M) mf.add_edge(1 + N + m, 1 + N + M, 1);
      int f = mf.run_destructive(0, 1 + N + M);
      if (f < M) {
        low = mid + 1; // the answer is in (mid,high]
      } else {
        high = mid;
      }
    }
    printf("%.8lf\\n", p[low - 1].t);
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;
#define repeat(i, n) for (int i = 0; i < (n); ++i)

template <typename T> class ford_fulkerson {
public:
  struct edge_t {
    int to;
    T cap;
    int rev;
  };
  static T infinity;

  ford_fulkerson() {}
  ford_fulkerson(int n) : graph(n) {}

  vector<vector<edge_t>> graph; // adjacency list

  int add_vertex() {
    graph.push_back(vector<edge_t>());
    return graph.size() - 1;
  }

  void add_edge(int from, T to, int cap) {
    graph[from].push_back((edge_t){to, cap, (int)graph[to].size()});
    graph[to].push_back((edge_t){from, 0, (int)graph[from].size() - 1});
  }

  vector<bool> used;

  T run_destructive(int s, int t) {
    T flow = 0;
    used.resize(graph.size());
    fill(used.begin(), used.end(), false);
    while (true) {
      const int f = dfs(s, t, infinity);
      if (f == 0)
        return flow;
      flow += f;
    }
  }

  // search augmenting pathes from `v' to `t', returns the volume of water `f'
  T dfs(int v, int t, T f) {
    if (v == t)
      return f; // base case
    used[v] = true;
    repeat(i, (int)graph[v].size()) { // for each adjacent nodes which are not
                                      // used and able to flow
      edge_t &e = graph[v][i];
      const int w = e.to;
      if (not used[w] and 0 < e.cap) {
        T d = dfs(w, t, min(f, e.cap)); // v -> w ->> t
        if (0 < d) {                    // let flow and make reverse capacity
          e.cap -= d;
          graph[w][e.rev].cap += d;
          return d;
        }
      }
    }
    return 0; // path not found
  }
};
template <> int ford_fulkerson<int>::infinity = 1e9;
template <> double ford_fulkerson<double>::infinity = 1 / (double)0;
int sq(int x) { return x * x; }
double hypot(int x, int y) { return sqrt(sq(x) + sq(y)); }
double distance(int ax, int ay, int bx, int by) {
  return hypot(ax - bx, ay - by);
}
template <class T, class S> double distance(const T &a, const S &b) {
  return hypot(a.x - b.x, a.y - b.y);
}

#define MAX_N 100
#define MAX_M 100
struct troop_t {
  int x, y, v;
};
struct base_t {
  int x, y;
};
double time(const troop_t &t, const base_t &b) {
  return distance(t, b) / (double)t.v;
}
struct path_t {
  int n, m;
  double t;
};
bool operator<(const path_t &a, const path_t &b) {
  return make_pair(a.t, make_pair(a.n, a.m)) <
         make_pair(b.t, make_pair(b.n, b.m));
}

int main() {
  while (true) {
    int N, M;
    cin >> N >> M;
    if (N == 0 or M == 0)
      break;
    static troop_t T[MAX_N];
    repeat(n, N) cin >> T[n].x >> T[n].y >> T[n].v;
    static base_t B[MAX_M];
    repeat(m, M) cin >> B[m].x >> B[m].y;

    static vector<path_t> p;
    repeat(n, N) repeat(m, M) p.push_back((path_t){n, m, time(T[n], B[m])});
    sort(p.begin(), p.end());

    int low = 1, high = (int)p.size() - 1; // the answer is in [low,high]
    while (low < high) {
      int mid = (low + high) / 2;
      ford_fulkerson<int> mf(1 + N + M + 1);
      repeat(n, N) mf.add_edge(0, 1 + n, 1);
      repeat(i, mid) mf.add_edge(1 + p[i].n, 1 + N + p[i].m, 1);
      repeat(m, M) mf.add_edge(1 + N + m, 1 + N + M, 1);
      int f = mf.run_destructive(0, 1 + N + M);
      if (f < M) {
        low = mid + 1; // the answer is in (mid,high]
      } else {
        high = mid;
      }
    }
    printf("%.8lf\\n", p[low - 1].t);
  }
  return 0;
}