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

/*
16:50 - 17:23
 */

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>

#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define IINF (INT_MAX)
#define EPS (1e-9)
#define equals(a, b) (fabs((a) - (b)) < EPS)
#define MAX 500
#define pow2(a) ((a) * (a))

using namespace std;

// Library - maxflow - begin 17:01
struct edge {
  int to, cap, rev;
  edge(int to = IINF, int cap = IINF, int rev = IINF)
      : to(to), cap(cap), rev(rev) {}
};

vector<vector<edge>> G;
bool used[MAX];

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

int dfs(int v, int t, int f) {
  if (v == t)
    return f;
  used[v] = true;
  for (int i = 0; i < G[v].size(); i++) {
    edge &e = G[v][i];
    if (!used[e.to] && e.cap > 0) {
      int d = dfs(e.to, t, min(f, e.cap));
      if (d > 0) {
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}

int max_flow(int s, int t) {
  int flow = 0;
  for (;;) {
    memset(used, 0, sizeof(used));
    int f = dfs(s, t, IINF);
    if (f == 0)
      return flow;
    flow += f;
  }
}

// Library - maxflow - end 17:07

struct Point {
  double x, y, v;
  Point(double x = IINF, double y = IINF, double v = IINF) : x(x), y(y), v(v) {}
};

struct Data {
  double cost;
  int from, to;
  Data(double cost = IINF, int from = IINF, int to = IINF)
      : cost(cost), from(from), to(to) {}
  bool operator<(const Data &a) const { return cost < a.cost; }
};

int N, M, source, sink;
Point troops[MAX];
Point base[MAX];
bool check[MAX];
vector<Data> info;

inline double getDist(Point a, Point b) {
  return sqrt(pow2(a.x - b.x) + pow2(b.y - a.y));
}

int main() {
  while (cin >> N >> M, N | M) {
    info.clear();
    rep(i, N) cin >> troops[i].x >> troops[i].y >> troops[i].v;
    rep(i, M) {
      cin >> base[i].x >> base[i].y;
      check[i] = false;
      rep(j, N) info.push_back(
          Data(getDist(base[i], troops[j]) / troops[j].v, j, N + i));
    }
    sort(info.begin(), info.end());
    source = N + M;
    sink = source + 1;
    G.resize(sink + 1);
    rep(i, sink + 1) G[i].clear();
    rep(i, N) add_edge(source, i, 1);
    rep(i, M) add_edge(N + i, sink, 1);
    int finish = 0;
    /*
    int sp = 0;
    rep(i,info.size()){
      add_edge(info[i].from,info[i].to,1);
      if(!check[info[i].to-N]){ finish++; check[info[i].to-N] = true; }
      sp = i + 1;
      if(finish == M)break;
    }
    */
    vector<vector<edge>> tmp = G;
    double ans = IINF;
    double L = 0, R = (1 << 27), H;
    rep(_, 100) {
      H = (L + R) * 0.5;
      G = tmp;
      rep(i, info.size()) {
        if (equals(info[i].cost, H) || info[i].cost < H)
          add_edge(info[i].from, info[i].to, 1);
        else
          break;
      }
      if (max_flow(source, sink) == M) {
        ans = min(ans, H);
        R = H;
      } else
        L = H;
    }

    cout << setiosflags(ios::fixed) << setprecision(8) << ans << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

/*
16:50 - 17:23
 */

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>

#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define IINF (INT_MAX)
#define EPS (1e-9)
#define equals(a, b) (fabs((a) - (b)) < EPS)
#define MAX 500
#define pow2(a) ((a) * (a))

using namespace std;

// Library - maxflow - begin 17:01
struct edge {
  int to, cap, rev;
  edge(int to = IINF, int cap = IINF, int rev = IINF)
      : to(to), cap(cap), rev(rev) {}
};

vector<vector<edge>> G;
bool used[MAX];

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

int dfs(int v, int t, int f) {
  if (v == t)
    return f;
  used[v] = true;
  for (int i = 0; i < G[v].size(); i++) {
    edge &e = G[v][i];
    if (!used[e.to] && e.cap > 0) {
      int d = dfs(e.to, t, min(f, e.cap));
      if (d > 0) {
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}

int max_flow(int s, int t) {
  int flow = 0;
  for (;;) {
    memset(used, 0, sizeof(used));
    int f = dfs(s, t, IINF);
    if (f == 0)
      return flow;
    flow += f;
  }
}

// Library - maxflow - end 17:07

struct Point {
  double x, y, v;
  Point(double x = IINF, double y = IINF, double v = IINF) : x(x), y(y), v(v) {}
};

struct Data {
  double cost;
  int from, to;
  Data(double cost = IINF, int from = IINF, int to = IINF)
      : cost(cost), from(from), to(to) {}
  bool operator<(const Data &a) const { return cost < a.cost; }
};

int N, M, source, sink;
Point troops[MAX];
Point base[MAX];
bool check[MAX];
vector<Data> info;

inline double getDist(Point a, Point b) {
  return sqrt(pow2(a.x - b.x) + pow2(b.y - a.y));
}

int main() {
  while (cin >> N >> M, N | M) {
    info.clear();
    rep(i, N) cin >> troops[i].x >> troops[i].y >> troops[i].v;
    rep(i, M) {
      cin >> base[i].x >> base[i].y;
      check[i] = false;
      rep(j, N) info.push_back(
          Data(getDist(base[i], troops[j]) / troops[j].v, j, N + i));
    }
    sort(info.begin(), info.end());
    source = N + M;
    sink = source + 1;
    G.resize(sink + 1);
    // rep(i,sink+1)G[i].clear();
    rep(i, N) add_edge(source, i, 1);
    rep(i, M) add_edge(N + i, sink, 1);
    int finish = 0;
    /*
    int sp = 0;
    rep(i,info.size()){
      add_edge(info[i].from,info[i].to,1);
      if(!check[info[i].to-N]){ finish++; check[info[i].to-N] = true; }
      sp = i + 1;
      if(finish == M)break;
    }
    */
    vector<vector<edge>> tmp = G;
    double ans = IINF;
    double L = 0, R = (1 << 27), H;
    rep(_, 100) {
      H = (L + R) * 0.5;
      G = tmp;
      rep(i, info.size()) {
        if (equals(info[i].cost, H) || info[i].cost < H)
          add_edge(info[i].from, info[i].to, 1);
        else
          break;
      }
      if (max_flow(source, sink) == M) {
        ans = min(ans, H);
        R = H;
      } else
        L = H;
    }

    cout << setiosflags(ios::fixed) << setprecision(8) << ans << endl;
  }
  return 0;
}