Problem p01279 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;

#define INF 10000000
#define SOUR 200
#define SINK 201

int N, M;
class Node {
public:
  vector<int> to;
};

class Edge {
public:
  int s, d;
  double c;
  Edge(int s, int d, double c) : s(s), d(d), c(c) {}

  bool operator<(const Edge &e) const { return c < e.c; }
};

int flow[202][202], capa[202][202];

int dfs(int p, int T, int mf, vector<Node> &graph, vector<int> &level,
        vector<bool> &finished) {
  if (p == T)
    return mf;
  if (finished[p])
    return 0;

  finished[p] = true;

  for (int i = 0; i < graph[p].to.size(); i++) {
    int next = graph[p].to[i], fw = capa[p][next] - flow[p][next];
    if (level[p] >= level[next])
      continue;
    if (fw <= 0)
      continue;

    int f = dfs(next, T, min(mf, fw), graph, level, finished);
    if (f > 0) {
      finished[p] = false;
      flow[p][next] += f;
      flow[next][p] -= f;
      return f;
    }
  }

  return 0;
}

int dinic(int S, int T, vector<Node> &graph) {
  bool end = false;
  int total = 0;
  while (!end) {
    end = true;
    vector<int> level(graph.size(), -1);
    level[S] = 0;

    queue<int> q;
    q.push(S);

    while (!q.empty()) {
      int n = q.front();
      q.pop();
      for (int i = 0; i < graph[n].to.size(); i++) {
        int next = graph[n].to[i];
        if (level[next] != -1)
          continue;
        if (capa[n][next] - flow[n][next] <= 0)
          continue;
        level[next] = level[n] + 1;
        q.push(next);
      }
    }

    if (level[T] == -1)
      break;

    vector<bool> finished(graph.size());
    while (1) {
      int fw = dfs(S, T, INF, graph, level, finished);
      if (fw <= 0)
        break;

      total += fw;
      end = false;
    }
  }

  return total;
}

bool calc(int &hi, int &lo, vector<Edge> &G, double &ans) {
  if (hi < lo)
    return false;
  int mi = (hi + lo) / 2;

  memset(flow, 0, sizeof(flow));
  memset(capa, 0, sizeof(capa));

  vector<Node> graph(205);
  for (int i = 0; i <= mi; i++) {
    graph[G[i].s].to.push_back(G[i].d);
    graph[G[i].d].to.push_back(G[i].s);
    graph[SOUR].to.push_back(G[i].s);
    graph[G[i].d].to.push_back(SINK);

    capa[G[i].s][G[i].d] = 1;
    capa[G[i].d][G[i].s] = 1;
    flow[G[i].d][G[i].s] = 1;

    capa[SOUR][G[i].s] = 1;
    capa[G[i].s][SOUR] = 1;
    flow[G[i].s][SOUR] = 1;

    capa[G[i].d][SINK] = 1;
    capa[SINK][G[i].d] = 1;
    flow[SINK][G[i].d] = 1;
  }
  if (dinic(SOUR, SINK, graph) == M) {
    hi = mi - 1;
    ans = min(G[mi].c, ans);
  } else {
    lo = mi + 1;
  }

  return true;
}

int main() {
  while (scanf("%d%d", &N, &M), (N || M)) {
    scanf("%d%d", &N, &M);
    double x[100], y[100], v[100];
    for (int i = 0; i < N; i++)
      scanf("%lf%lf%lf", &x[i], &y[i], &v[i]);

    vector<Edge> e;
    for (int j = 0; j < M; j++) {
      double xx, yy;
      scanf("%lf%lf", &xx, &yy);
      for (int i = 0; i < N; i++) {
        double dist = (x[i] - xx) * (x[i] - xx) + (y[i] - yy) * (y[i] - yy);
        e.push_back(Edge(i, j + 100, sqrt(dist) / v[i]));
      }
    }

    sort(e.begin(), e.end());

    int hi = e.size() - 1, lo = 0;
    double ans = INF;

    while (1) {
      if (!calc(hi, lo, e, ans))
        break;
    }

    printf("%.20lf\n", ans);
  }
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;

#define INF 10000000
#define SOUR 200
#define SINK 201

int N, M;
class Node {
public:
  vector<int> to;
};

class Edge {
public:
  int s, d;
  double c;
  Edge(int s, int d, double c) : s(s), d(d), c(c) {}

  bool operator<(const Edge &e) const { return c < e.c; }
};

int flow[202][202], capa[202][202];

int dfs(int p, int T, int mf, vector<Node> &graph, vector<int> &level,
        vector<bool> &finished) {
  if (p == T)
    return mf;
  if (finished[p])
    return 0;

  finished[p] = true;

  for (int i = 0; i < graph[p].to.size(); i++) {
    int next = graph[p].to[i], fw = capa[p][next] - flow[p][next];
    if (level[p] >= level[next])
      continue;
    if (fw <= 0)
      continue;

    int f = dfs(next, T, min(mf, fw), graph, level, finished);
    if (f > 0) {
      finished[p] = false;
      flow[p][next] += f;
      flow[next][p] -= f;
      return f;
    }
  }

  return 0;
}

int dinic(int S, int T, vector<Node> &graph) {
  bool end = false;
  int total = 0;
  while (!end) {
    end = true;
    vector<int> level(graph.size(), -1);
    level[S] = 0;

    queue<int> q;
    q.push(S);

    while (!q.empty()) {
      int n = q.front();
      q.pop();
      for (int i = 0; i < graph[n].to.size(); i++) {
        int next = graph[n].to[i];
        if (level[next] != -1)
          continue;
        if (capa[n][next] - flow[n][next] <= 0)
          continue;
        level[next] = level[n] + 1;
        q.push(next);
      }
    }

    if (level[T] == -1)
      break;

    vector<bool> finished(graph.size());
    while (1) {
      int fw = dfs(S, T, INF, graph, level, finished);
      if (fw <= 0)
        break;

      total += fw;
      end = false;
    }
  }

  return total;
}

bool calc(int &hi, int &lo, vector<Edge> &G, double &ans) {
  if (hi < lo)
    return false;
  int mi = (hi + lo) / 2;

  memset(flow, 0, sizeof(flow));
  memset(capa, 0, sizeof(capa));

  vector<Node> graph(205);
  for (int i = 0; i <= mi; i++) {
    graph[G[i].s].to.push_back(G[i].d);
    graph[G[i].d].to.push_back(G[i].s);
    graph[SOUR].to.push_back(G[i].s);
    graph[G[i].d].to.push_back(SINK);

    capa[G[i].s][G[i].d] = 1;
    capa[G[i].d][G[i].s] = 1;
    flow[G[i].d][G[i].s] = 1;

    capa[SOUR][G[i].s] = 1;
    capa[G[i].s][SOUR] = 1;
    flow[G[i].s][SOUR] = 1;

    capa[G[i].d][SINK] = 1;
    capa[SINK][G[i].d] = 1;
    flow[SINK][G[i].d] = 1;
  }
  if (dinic(SOUR, SINK, graph) == M) {
    hi = mi - 1;
    ans = min(G[mi].c, ans);
  } else {
    lo = mi + 1;
  }

  return true;
}

int main() {
  while (scanf("%d%d", &N, &M), (N || M)) {
    double x[100], y[100], v[100];
    for (int i = 0; i < N; i++)
      scanf("%lf%lf%lf", &x[i], &y[i], &v[i]);

    vector<Edge> e;
    for (int j = 0; j < M; j++) {
      double xx, yy;
      scanf("%lf%lf", &xx, &yy);
      for (int i = 0; i < N; i++) {
        double dist = (x[i] - xx) * (x[i] - xx) + (y[i] - yy) * (y[i] - yy);
        e.push_back(Edge(i, j + 100, sqrt(dist) / v[i]));
      }
    }

    sort(e.begin(), e.end());

    int hi = e.size() - 1, lo = 0;
    double ans = INF;

    while (1) {
      if (!calc(hi, lo, e, ans))
        break;
    }

    printf("%.20lf\n", ans);
  }
}