Problem:
Problem G:
Defend the Bases
A country Gizevom is being under a sneak and fierce attack by their foe. They have to deploy one or
more troops to every base immediately in order to defend their country. Otherwise their foe would take
all the bases and declare "All your base are belong to us."
You are asked to write a program that calculates the minimum time required for deployment, given the
present positions and marching speeds of troops and the positions of the bases.
Input
The input consists of multiple datasets. Each dataset has the following format:
N M
x
1
y
1
v
1
x
2
y
2
v
2
...
x
N
y
N
v
N
x'
1
y'
1
x'
2
y'
2
...
x'
M
y'
M
N
is the number of troops (1 ≤
N
≤ 100);
M
is the number of bases (1 ≤
M
≤ 100); (
x
i
,
y
i
) denotes the present position of
i
-th troop;
v
i
is the speed of the
i
-th troop (1 ≤
v
i
≤ 100); (
x'
j
,
y'
j
) is the position of the
j
-th base.
All the coordinates are integers between 0 and 10000 inclusive.
The last dataset is followed by a line containing two zeros. This line is not a part of any dataset and should not be processed.
Output
For each dataset, print the minimum required time in a line.
Sample Input
2 2
10 20 1
0 10 1
0 10
10 0
0 0
Output for the Sample Input
14.14213562

Submitted solutions:

code_snippet: #include <bits/stdc++.h>


using namespace std;
//make -f ../makefile SRC=
/*
bs on max time available for max flow >= M

*/

//------------------------------------------------------------------------------
bool DEBUG = false;
const double INF = 1e9;
const double EPS = 1e-9;

const int MAX_N = 100;
// troops:
static double X[MAX_N];
static double Y[MAX_N];
static double VEL[MAX_N];
// bases:
static double BX[MAX_N];
static double BY[MAX_N];

static double dist[MAX_N][MAX_N]; // dist from troop v to base w
const int MAX_NN = 2*MAX_N + 2;
static int level[MAX_NN];
static int start[MAX_NN];

//------------------------------------------------------------------------------
struct SEdge
{
    int m, w, c;
    bool operator<(const SEdge& other) const
    {
        return m < other.m;
    }

    SEdge(): m(-1), w(-1), c(INF) {}
    SEdge(int e1, int v2, int cost=0): m(e1), w(v2), c(cost) {}
    void debug() const { printf("(%d, %d, %d)\n", m, w, c); }
};

typedef vector<SEdge> SEdges;
typedef vector<SEdges> Graph;


//------------------------------------------------------------------------------
struct Edge
{
    int w, f, c, j;

    bool operator<(const Edge& other) const
    {
        return f < other.f;
    }

    Edge(): w(-1), f(0), c(0), j(-1) {}
    Edge(int v2, int flow, int capacity, int reverse_edge): w(v2), f(flow), c(capacity), j(reverse_edge) {}
    void debug() const { printf("(%d, %d, %d, %d)\n", w, f, c, j); }
};

typedef vector<Edge> Edges;
typedef vector<Edges> GRAPH;

//------------------------------------------------------------------------------
void add_edge(int NN, GRAPH& GG, int v, int w, int c=1)
{
    // forward edge:
    Edge e1(w, 0, c, GG[w].size());

    // backward edge:
    Edge e2(v, 0, 0, GG[v].size());

    GG[v].push_back( e1 );
    GG[w].push_back( e2 );
}

//------------------------------------------------------------------------------
bool bfs(int NN, GRAPH& GG, int src, int dest)
{
    //--------------------------------------------------------------------------
    // setup params:
    for (int v=0; v<NN; ++v) level[v] = -1;

    queue<int> Q;
    Q.push(src);
    level[src] = 0;

    //--------------------------------------------------------------------------
    // search:
    while (!Q.empty())
    {
        int v = Q.front(); Q.pop();
        for (Edge e: GG[v])
        {
            if (level[e.w] < 0 && e.f < e.c)
            {
                level[e.w] = level[v] + 1;
                Q.push(e.w);
            }
        }
    }

    //--------------------------------------------------------------------------
    // is dest reachable from src?
    return level[dest] >= 0;
}

int send_flow(int NN, GRAPH& GG, int v, int dest, int flow)
{
    if (v == dest) return flow;
    for (; start[v]<GG[v].size(); start[v]++)
    { 
        Edge& e = GG[v][start[v]];
        if (level[e.w] == level[v] + 1 && e.f < e.c)
        {
            int min_flow = min(flow, e.c-e.f);
            int new_flow = send_flow(NN, GG, e.w, dest, min_flow);
  
            if (new_flow)
            { 
                e.f += new_flow;
                GG[e.w][e.j].f -= new_flow;
                return new_flow; 
            }
        }
    }
    return 0;
}


//------------------------------------------------------------------------------
int dinic(int NN, GRAPH& GG, int src, int dest)
{
    //if (DEBUG) {for (int v=0; v<NN; ++v) for (Edge e: GG[v]) { printf("%d -> ", v); e.debug(); }}

    //--------------------------------------------------------------------------
    // base cases:
    if (dest == src) return 0;

    //--------------------------------------------------------------------------
    // init params:
    int res = 0;

    //--------------------------------------------------------------------------
    // compute:
    while (bfs(NN, GG, src, dest))
    {
        for (int v=0; v<NN; ++v) start[v] = 0;
        while (int flow = send_flow(NN, GG, src, dest, INF)) res += flow;
    }

    //--------------------------------------------------------------------------
    // report:
    return res;
}
//------------------------------------------------------------------------------
void init(int N, int M)
{
    for (int v=0; v<N; ++v)
        for (int w=0; w<M; ++w)
            dist[v][w] = sqrt( (X[v]-BX[w])*(X[v]-BX[w]) + (Y[v]-BY[w])*(Y[v]-BY[w]) );
}

GRAPH setup(int N, int M, double max_time)
{
    int NN = M+N+2;
    GRAPH GG(NN);
    int S = NN-2;
    int D = NN-1;
    for (int v=0; v<N; ++v) add_edge(NN, GG, S, v, 1);
    for (int w=0; w<M; ++w) add_edge(NN, GG, w+N, D, 1);

    for (int v=0; v<N; ++v)
        for (int w=0; w<M; ++w)
            if (VEL[v]*max_time >= dist[v][w])
                add_edge(NN, GG, v, w+N, 1);
    return GG;
}

bool feasible(int N, int M, double max_time)
{
    GRAPH GG = setup(N, M, max_time);
    int NN = M+N+2;
    int S = NN-2;
    int D = NN-1;
    int res = dinic(NN, GG, S, D);
    return res >= M;
}

double bs(int N, int M, double L, double R)
{
    while (abs(R-L) > EPS)
    {
        if (DEBUG) printf("L=%lf, R=%lf\n", L, R);
        double MID = 0.5*(L+R);
        if (feasible(N, M, MID)) R = MID;
        else L = MID;
    }
    return L;

}

//------------------------------------------------------------------------------
void solve(int N, int M)
{
    init(N, M);
    double res = bs(N, M, 0, INF);
    printf("%0.10lf\n", res);
}

//------------------------------------------------------------------------------
void test()
{

}

//------------------------------------------------------------------------------
int main()
{
    //test(); return 0;
    //DEBUG = true;
    //--------------------------------------------------------------------------
    int N, M, src, dest, v, w, num;
    while (true)
    {
        num = scanf("%d %d ", &N, &M);
        if (N == 0 && M == 0) break;
        for (int v=0; v<N; ++v) num = scanf("%lf %lf %lf ", &X[v], &Y[v], &VEL[v]);
        for (int w=0; w<M; ++w) num = scanf("%lf %lf ", &BX[w], &BY[w]);
        solve(N, M);
    }
    //--------------------------------------------------------------------------
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 3792
final_rank: 17

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)

template<class T>
using vi = vector<T>;

template<class T>
using vii = vector<vi<T>>;

template<class T>
using viii = vector<vii<T>>;

struct Dinic {
private:
    const long long inf = 1e18;
    vector<int> dist; //sからの距離
    vector<int> iter; //どこまで調べたか
public:
    struct edge {
        int to, rev; long long cap;
        edge(int t = 0, int r = 0, long long c = 0LL) : to(t), rev(r), cap(c) {}
    };

    int n;
    vector<vector<edge>> to;

    Dinic(int n_ = 1) : n(n_), to(n_), dist(n_), iter(n_) {}

    void addedge(int u, int v, long long cap) {//u->vにcapの容量
        int su = (int)to[u].size(), sv = (int)to[v].size();
        to[u].push_back({ v, sv, cap });
        to[v].push_back({ u, su, 0 });
    }

    long long dfs(int v, int t, long long f) { //t: 終点, f: flow
        if (v == t) return f;
        int sv = (int)to[v].size();
        for (int& i = iter[v]; i < sv; i++) {
            edge& nv = to[v][i];
            if (dist[nv.to] <= dist[v] || nv.cap == 0) continue; //here
            long long nf = dfs(nv.to, t, min(f, nv.cap));
            if (nf > 0) {
                nv.cap -= nf;
                to[nv.to][nv.rev].cap += nf;
                return nf;
            }
        }
        return 0;
    }

    void bfs(int s) {
        dist.assign(n, -1);
        queue<int> q;
        q.push(s);
        dist[s] = 0;
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            for (auto nv : to[v]) {
                if (nv.cap > 0 && dist[nv.to] < 0) {
                    dist[nv.to] = dist[v] + 1;
                    q.push(nv.to);
                }
            }
        }
    }

    long long maxflow(int s, int t) {//s:始点, t:終点
        long long res = 0, flow = 0;
        while (true) {
            bfs(s);
            if (dist[t] < 0) break;

            iter.assign(n, 0);
            while (flow = dfs(s, t, inf)) res += flow;
        };
        return res;
    }
};


#include <cmath>
#include <iomanip>

int main()
{
    int n, m;
    while (cin >> n >> m, n) {
        vi<double> x(n), y(n), v(n);
        vi<double> bx(m), by(m);
        rep(i, n) cin >> x[i] >> y[i] >> v[i];
        rep(j, m) cin >> bx[j] >> by[j];
        
        auto dist = [&](int i, int j) {
            return sqrt((x[i] - bx[j]) * (x[i] - bx[j]) + (y[i] - by[j]) * (y[i] - by[j])) / v[i];
        };

        double ok = 1e6, ng = -1e-10;
        while (abs(ok - ng) > 1e-10) {
            double mid = (ok + ng) / 2;
            Dinic dn(n + m + 2);
            int S = n + m, T = n + m + 1;
            rep(i, n) dn.addedge(S, i, 1);
            rep(j, m) dn.addedge(j + n, T, 1);


            rep(i, n) rep(j, m) {
                if (dist(i, j) <= mid) dn.addedge(i, j + n, 1);
            }

            int flow = dn.maxflow(S, T);
            if (flow == m) ok = mid;
            else ng = mid;
        }

        cout << fixed << setprecision(12) << ok << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 3936
final_rank: 18

code_snippet: #include <stdio.h>
#include <math.h>
#include <vector>
using namespace std;

int troop[128][3], base[128][2];
double tm[128][128];

int left[128], right[128], vis[128];
vector<int> ed[128];

int sqr(int a) {
    return a * a;
}

int match(int x) {
    vis[x] = 1;
    for (int i : ed[x]) {
        if (right[i] == 0 || (!vis[right[i]] && match(right[i]))) {
            left[x] = i;
            right[i] = x;
            return 1;
        }
    }
    return 0;
}

int main(void) {
    int n, m, mcnt;
    double hi, lo, mid;
    while (1) {
        scanf("%d %d", &n, &m);
        if (n + m == 0) break;
        if (m > n) return 1;
        for (int i = 1; i <= n; i++) {
            scanf("%d %d %d", &troop[i][0], &troop[i][1], &troop[i][2]);
        }
        for (int i = 1; i <= m; i++) {
            scanf("%d %d", &base[i][0], &base[i][1]);
        }

        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                tm[i][j] = sqrt(sqr(troop[i][0] - base[j][0]) +
                    sqr(troop[i][1] - base[j][1])) / troop[i][2];
            }
        }

        hi = 1012345678.9;
        lo = 0.0;
        for (int i = 0; i < 0401; i++) {
            mid = (hi + lo) / 2.0;
            for (int j = 1; j <= n; j++) {
                ed[j].clear();
                for (int k = 1; k <= m; k++) {
                    if (tm[j][k] < mid) ed[j].push_back(k);
                    right[k] = 0;
                }
                left[j] = 0;
            }
            mcnt = 0;
            for (int j = 1; j <= n; j++) {
                for (int k = 1; k <= n; k++) vis[k] = 0;
                mcnt += match(j);
            }
            if (mcnt == m) hi = mid;
            else lo = mid;
        }
        printf("%.9f\n", hi);
    }
    return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 3032
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
struct point{
  double x, y;
  point(){
  }
  point(double x, double y): x(x), y(y){
  }
  point operator -(point P){
    return point(x - P.x, y - P.y);
  }
};
double abs(point P){
  return sqrt(P.x * P.x + P.y * P.y);
}
double dist(point P, point Q){
  return abs(Q - P);
}
struct ford_fulkerson{
  struct edge{
    int to, rev, cap;
    edge(int to, int rev, int cap): to(to), rev(rev), cap(cap){
    }
  };
  int N;
  vector<vector<edge>> G;
  ford_fulkerson(int N): N(N), G(N){
  }
  void add_edge(int from, int to){
    G[from].push_back(edge(to, G[to].size(), 1));
    G[to].push_back(edge(from, G[from].size() - 1, 0));
  }
  int max_flow(int s, int t){
    int F = 0;
    while (true){
      vector<bool> used(N, false);
      vector<int> pv(N), pe(N);
      used[s] = true;
      queue<int> Q;
      Q.push(s);
      while (!Q.empty()){
        int v = Q.front();
        Q.pop();
        int cnt = G[v].size();
        for (int i = 0; i < cnt; i++){
          int w = G[v][i].to;
          if (!used[w] && G[v][i].cap > 0){
            used[w] = true;
            pv[w] = v;
            pe[w] = i;
            Q.push(w);
          }
        }
      }
      if (!used[t]){
        break;
      }
      F++;
      for (int i = t; i != s; i = pv[i]){
        G[pv[i]][pe[i]].cap--;
        G[i][G[pv[i]][pe[i]].rev].cap++;
      }
    }
    return F;
  }
};
int main(){
  cout << fixed << setprecision(20);
  while (true){
    int N, M;
    cin >> N >> M;
    if (N == 0 && M == 0){
      break;
    }
    vector<point> P(N);
    vector<int> v(N);
    for (int i = 0; i < N; i++){
      cin >> P[i].x >> P[i].y >> v[i];
    }
    vector<point> Q(M);
    for (int i = 0; i < M; i++){
      cin >> Q[i].x >> Q[i].y;
    }
    double tv = 100000, fv = 0;
    for (int i = 0; i < 50; i++){
      double mid = (tv + fv) / 2;
      ford_fulkerson G(N + M + 2);
      for (int j = 0; j < N; j++){
        G.add_edge(N + M, j);
      }
      for (int j = 0; j < M; j++){
        G.add_edge(N + j, N + M + 1);
      }
      for (int j = 0; j < N; j++){
        for (int k = 0; k < M; k++){
          if (dist(P[j], Q[k]) < v[j] * mid){
            G.add_edge(j, N + k);
          }
        }
      }
      if (G.max_flow(N + M, N + M + 1) == M){
        tv = mid;
      } else {
        fv = mid;
      }
    }
    cout << tv << endl;
  }
}
accuracy: 1
time_ms: 540
memory_kb: 3792
final_rank: 19

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <utility>
using namespace std;
const int inf = 1e9;

template <typename T>
struct MaxFlow{
    struct edge{
        int to, rev;
        T cap;
        edge(int t, int r, T c):to(t),rev(r),cap(c){}
        edge(){}
    };
    vector<vector<edge>> graph;
    T zero;
    T inf;
    
    MaxFlow(int n, T zero, T inf):zero(zero),inf(inf){
        graph.resize(n);
    }
    void add_edge(int from, int to, T cap){
        graph[from].emplace_back(to, graph[to].size(), cap);
        graph[to].emplace_back(from, (int)graph[from].size()-1, zero);
    }
    T dfs(int v, int g, T flow, vector<bool>& used){
        if(used[v]) return zero;
        used[v] = true;
        if(v == g) return flow;
    
        for(auto &e: graph[v]){
            if(zero < e.cap){
                T ret = dfs(e.to, g, min(flow, e.cap), used);
                if(zero < ret){
                    e.cap -= ret;
                    graph[e.to][e.rev].cap += ret;
                    return ret;
                }
            }
        }
        return zero;
    }
    T exec(int s, int g){
        T res = zero;
        while(1){
            vector<bool> used(graph.size(), false);
            T ret = dfs(s, g, inf, used);
            if(ret == zero) break;
            res += ret;
        }
        return res;
    }
};


int main(){
    while(1){
        int n,m;
        cin >> n >> m;
        if(n == 0) break;

        vector<int> x(n),y(n),v(n);
        for(int i=0; i<n; i++){
            cin >> x[i] >> y[i] >> v[i];
        }
        vector<int> xx(m), yy(m);
        for(int i=0; i<m; i++){
            cin >> xx[i] >> yy[i];
        }
        vector<pair<double, pair<int,int>>> edges;
        for(int i=0; i<n; i++){
            for(int j=0; j<m; j++){
                edges.push_back({sqrt((xx[j]-x[i])*(xx[j]-x[i])+(yy[j]-y[i])*(yy[j]-y[i]))/v[i], {i, j}});
            }
        }
        sort(edges.begin(), edges.end());

        int lb=0, ub=n*m;
        while(ub-lb>1){
            int mid = (lb+ub)/2;
            MaxFlow<int> mf(n+m+2, 0, inf);
            for(int i=0; i<n; i++){
                mf.add_edge(n+m, i, 1);
            }
            for(int i=0; i<m; i++){
                mf.add_edge(n+i, n+m+1, 1);
            }
            for(int i=0; i<mid; i++){
                mf.add_edge(edges[i].second.first, edges[i].second.second +n, 1);
            }
            int ret = mf.exec(n+m, n+m+1);
            if(ret == m){
                ub = mid;
            }else{
                lb = mid;
            }
        }
        cout << fixed << setprecision(10);
        cout << edges[ub-1].first << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3632
final_rank: 13

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 210

struct Info{
	double x,y,speed;
};

struct Data{
	Data(double arg_time,int arg_index){
		time = arg_time;
		index = arg_index;
	}
	bool operator<(const struct Data &arg) const{
		return time < arg.time;
	}
	double time;
	int index;
};

int N,M;
int V; //頂点数
vector<int> G[NUM]; //グラフの隣接リスト表現
int match[NUM]; //マッチングのペア
bool used[NUM]; //DFSですでに調べたかのフラグ
Info troops[100],bases[100];
vector<Data> DIST[100];


//fromとtoを結ぶ辺をグラフに追加する
void add_edge(int from,int to){
	G[from].push_back(to);
	G[to].push_back(from);
}

//増加パスをDFSで探す(node_idのペアを探す)
int dfs(int node_id){
	used[node_id] = true;

	for(int i = 0; i < G[node_id].size(); i++){
		int adj_node_id = G[node_id][i],pair_id = match[adj_node_id];
		if((pair_id < 0)|| //隣接するノードに、まだペアが存在しない
				(used[pair_id] == false && dfs(pair_id) == true)){

			match[node_id] = adj_node_id;
			match[adj_node_id] = node_id;
			return true;
		}
	}
	return false;
}


int bipartie_matching(){
	int ret = 0;
	for(int i = 0; i < V; i++)match[i] = -1; //ペアなしにしておく
	for(int node_id = 0; node_id < V; node_id++){
		if(match[node_id] < 0){ //node_idにペアがいない場合
			for(int i = 0; i < V; i++)used[i] = false;
			if(dfs(node_id)){ //増加パスが存在する場合
				ret++;
			}
		}
	}
	return ret;
}

bool is_OK(double time){
	for(int i = 0; i < NUM; i++)G[i].clear();

	int left,right,m,max_index;


	//troopから、time内に到達できる基地に辺を張る
	for(int i = 0; i < N; i++){
		left = 0,right = M-1,m = (left+right)/2;
		max_index = -1;

		while(left <= right){
			if(DIST[i][m].time <= time){
				max_index = m;
				left = m+1; //より右へ
			}else{
				right = m-1; //より左へ
			}
			m = (left+right)/2;
		}

		if(max_index == -1)continue; //到達できる基地がない

		for(int k = 0; k <= max_index; k++){
			add_edge(i,N+DIST[i][k].index);
		}
	}

	return  bipartie_matching() == M;
}

double calc_time(Info a,Info b){
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y))/a.speed;
}


void func(){

	for(int i = 0; i < 100; i++)DIST[i].clear();

	V = N+M;

	for(int i = 0; i < N; i++){
		scanf("%lf %lf %lf",&troops[i].x,&troops[i].y,&troops[i].speed);
	}

	for(int i = 0; i < M; i++){
		scanf("%lf %lf",&bases[i].x,&bases[i].y);
	}

	double tmp_time;

	//troopとbaseの時間距離を求める
	for(int i = 0; i < N; i++){
		for(int k = 0; k < M; k++){
			tmp_time = calc_time(troops[i],bases[k]);
			DIST[i].push_back(Data(tmp_time,k));
		}
		sort(DIST[i].begin(),DIST[i].end());
	}

	double ans = 99999999999.0;
	double left = 0.0,right = ans,m = (left+right)/2;

	while(right-left > EPS){
		if(is_OK(m)){
			ans = m;
			right = m-EPS;
		}else{
			left = m+EPS;
		}
		m = (left+right)/2;
	}

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

int main(){

	while(true){
		scanf("%d %d",&N,&M);
		if(N == 0 && M == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3412
final_rank: 7

code_snippet: #include <bits/stdc++.h>

#define FOR(i,a,b) for(int i= (a); i<((int)b); ++i)
#define RFOR(i,a) for(int i=(a); i >= 0; --i)
#define FOE(i,a) for(auto i : a)
#define ALL(c) (c).begin(), (c).end()
#define RALL(c) (c).rbegin(), (c).rend()
#define DUMP(x)  cerr << #x << " = " << (x) << endl;
#define SUM(x) std::accumulate(ALL(x), 0LL)
#define MIN(v) *std::min_element(v.begin(), v.end())
#define MAX(v) *std::max_element(v.begin(), v.end())
#define EXIST(v,x) (std::find(v.begin(), v.end(), x) != v.end())
#define BIT(n) (1LL<<(n))
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());

typedef long long LL;
template<typename T> using V = std::vector<T>;
template<typename T> using VV = std::vector<std::vector<T>>;
template<typename T> using VVV = std::vector<std::vector<std::vector<T>>>;
template<class T> inline T ceil(T a, T b) { return (a + b - 1) / b; }
template<class T> inline void print(T x) { std::cout << x << std::endl; }
template<class T> inline bool inside(T y, T x, T H, T W) {return 0 <= y and y < H and 0 <= x and x < W; }
inline double distance(double y1, double x1, double y2, double x2) { return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); }

const int INF = 1L << 30;
const double EPS = 1e-9;
const std::string YES = "YES", Yes = "Yes", NO = "NO", No = "No";
const std::vector<int> dy = { 0, 1, 0, -1 }, dx = { 1, 0, -1, 0 };    // 4近傍（右, 下, 左, 上）

using namespace std;

struct Edge {
    const int to;         // 行き先のノードid
    int flow;             // 流量
    const int cap;        // 容量
    const int rev;        // 逆辺のノードid
    const bool is_rev;    // 逆辺かどうか
    Edge(int to, int flow, int cap, int rev, bool is_rev) : to(to), flow(flow), cap(cap), rev(rev), is_rev(is_rev) {
        assert(this->cap >= 0);
    }
};

// 最大流問題をO(F|E|)で解く
class FordFulkerson {
public:
    const unsigned int num_of_node = 0;   // ノード数
    map<int, vector<Edge>> G;             // グラフの隣接リスト表現

    FordFulkerson(unsigned int num_of_node) : num_of_node(num_of_node) {
    }

    // fromからtoへ向かう容量capの辺とその逆辺をグラフに追加する
    void add_edge(int from, int to, int cap) {
        this->G[from].emplace_back(Edge(to, 0, cap, (int)this->G[to].size(), false));          // 辺
        this->G[to].emplace_back(Edge(from, cap, cap, (int)this->G[from].size() - 1, true));   // 逆辺
    }

    // sからtへの最大流を求める O(F|E|)
    int max_flow(int s, int t) {
        int flow = 0;
        while (true) {
            vector<bool> used(this->num_of_node, false); // DFSですでに調べたかのフラグ
            int f = dfs(s, t, INT_MAX, used);
            if (f == 0) { return flow; }
            flow += f;
        }
    }

    // 水の流れたエッジを取得する
    set<pair<int, int>> get_used_edges() {
        set<pair<int, int>> used_edges;

        for (auto p : this->G) {
            int from = p.first;
            for (Edge edge : p.second) {
                int flow = edge.flow;
                bool is_rev = edge.is_rev;

                if (not is_rev and flow > 0) {
                    int to = edge.to;
                    used_edges.insert(make_pair(from , to));
                }
            }
        }
        return used_edges;
    }

private:
    // vからtへf流したときの流れた量
    int dfs(int from, int to, int f, vector<bool> &used) {
        if (from == to) { return f; }
        used[from] = true;
        for (Edge &e : G[from]) {
            int rest = e.cap - e.flow;
            if (!used[e.to] && rest > 0) {
                int d = dfs(e.to, to, min(f, rest), used);
                if (d > 0) {
                    e.flow += d;                 // 辺
                    G[e.to][e.rev].flow -= d;    // 逆辺
                    return d;
                }
            }
        }
        return 0;
    }

};


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    while (true) {
        int N, M;
        cin >> N >> M;
        if (N == 0 and M == 0) { break; }

        V<tuple<int, int, int>> troops;
        FOR(i, 0, N) {
            int x, y, v;
            cin >> x >> y >> v;
            troops.emplace_back(make_tuple(x, y, v));
        }
        V<tuple<int, int>> bases;
        FOR(i, 0, M) {
            int x, y;
            cin >> x >> y;
            bases.emplace_back(make_tuple(x, y));

        }

        V<tuple<int, int, double>> data;    // 軍i、基地j、時間
        FOR(i, 0, troops.size()) {
            FOR(j, 0, bases.size()) {
                int x1, y1, v1, x2, y2;
                tie(x1, y1, v1) = troops[i];
                tie(x2, y2) = bases[j];
                double t = distance(y1, x1, y2, x2) / (1.0 * v1);
                data.emplace_back(make_tuple(i, troops.size() + j, t));
            }
        }

        // [low, high)
        double low = -1, high = INF - 1, ans = -1;
        FOR(_, 0, 100) {
            double middle = (low + high) / 2.0;

            FordFulkerson ff(N + M + 2);
            FOE(a, data) {
                int i, j;
                double t;
                tie(i, j, t) = a;
                if (t < middle + EPS) {
                    ff.add_edge(i, j, 1);
                }
            }
            int source = N + M;
            int sink = source + 1;

            FOR(i, 0, N) {
                ff.add_edge(source, i, 1);
            }
            FOR(j, 0, M) {
                ff.add_edge(N + j, sink, 1);
            }

            int flow = ff.max_flow(source, sink);

            if (flow == M) {
                ans = middle;
                high = middle;
            }
            else {
                low = middle;
            }
        }
        printf("%.10f\n", ans);
    }

    return 0;
}
accuracy: 1
time_ms: 930
memory_kb: 3896
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;

using pii = pair<int, int>;
using ll = long long;
using ull = unsigned long long;

constexpr int INF = 1e9;
constexpr ll INFLL = 1e18;

using graph = vector<vector<int>>;

bool dfs(graph const& g, int v, vector<int>& match, vector<bool>& used) {
    used[v] = true;
    for(auto u : g[v]) {
        int w = match[u];
        if(w < 0 || !used[w] && dfs(g, w, match, used)) {
            match[v] = u;
            match[u] = v;
            return true;
        }
    }
    return false;
}

int bipartite_matching(graph const& g) {
    int const V = g.size();
    vector<int> match(V, -1);
    int res = 0;
    for(int v = 0; v < V; ++v) {
        if(match[v] < 0) {
            vector<bool> used(V);
            if(dfs(g, v, match, used)) {
                res++;
            }
        }
    }
    return res;
}

int main() {
    int N, M;
    while(cin >> N >> M, N) {
        vector<double> x1(N), y1(N), v(N);
        vector<double> x2(M), y2(M);
        for(int i = 0; i < N; ++i) {
            cin >> x1[i] >> y1[i] >> v[i];
        }
        for(int i = 0; i < M; ++i) {
            cin >> x2[i] >> y2[i];
        }

        double lb = 0, ub = INF;
        for(int i = 0; i < 60; ++i) {
            double mid = (lb + ub) / 2;
            graph g(N + M);
            for(int i = 0; i < N; ++i) {
                for(int j = 0; j < M; ++j) {
                    double t = hypot(x1[i] - x2[j], y1[i] - y2[j]) / v[i];
                    if(t <= mid) {
                        g[i].push_back(j + N);
                    }
                }
            }
            int m = bipartite_matching(g);
            if(bipartite_matching(g) == M) {
                ub = mid;
            } else {
                lb = mid;
            }
        }

        cout << fixed << setprecision(10) << lb << endl;
    }
}
accuracy: 1
time_ms: 180
memory_kb: 3364
final_rank: 9

code_snippet: #include<bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
#define MAX_V 1000
#define INF 1<<29
using namespace std;
 
 
//  geometry
 
 
typedef double D;
typedef complex<D> P;
const D EPS = 1e-9;
#define X real()
#define Y imag()
 
//  flow
 
 
struct edge{int to,cap,rev;};
vector<edge>G[MAX_V];
int level[MAX_V];
int iter[MAX_V];
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});
}
void bfs(int s){
  memset(level,-1,sizeof(level));
  queue<int>q;
  level[s]=0;
  q.push(s);
  while(!q.empty()){
    int v=q.front();q.pop();
    for(int i=0;i<G[v].size();i++){
      edge &e=G[v][i];
      if(e.cap>0&&level[e.to]<0){
    level[e.to]=level[v]+1;
    q.push(e.to);
      }
    }
  }
}
int dfs(int v,int t,int f){
  if(v==t)return f;
  for(int &i=iter[v];i<G[v].size();i++){
    edge &e=G[v][i];
    if(e.cap>0&&level[v]<level[e.to]){
      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;
  while(1){
    bfs(s);
    if(level[t]<0)return flow;
    memset(iter,0,sizeof(iter));
    int f;
    while((f=dfs(s,t,INF))>0){
      flow+=f;
    }
  }
}
 
void init(){
  r(i,MAX_V)G[i].clear();
  r(i,MAX_V)level[i]=0;
  r(i,MAX_V)iter[i]=0;
}
 
int n,m;
double xx,yy,vv[101];
double di[101][101];
vector<P>v,vp;
 
int main(){
  while(cin>>n>>m,n){
    vp.clear();
    v.clear();
    r(i,n){
      cin>>xx>>yy>>vv[i];
      v.push_back(P(xx,yy));
    }
    r(i,m){
      cin>>xx>>yy;
      P pt=P(xx,yy);
      vp.push_back(pt);
    }
    r(i,n)r(j,m)di[i][j]=abs(vp[j]-v[i])/vv[i];
    D l=0,r=1e9;
    r(i,77){
       
      init();
      D mid=(l+r)/2;
       
      r(j,n)r(k,m)if(di[j][k]<=mid){
        add_edge(j+1,k+201,1);
      }
      r(j,n)add_edge(0,j+1,1);
      r(j,m)add_edge(j+201,500,1);
 
      int ans=max_flow(0,500);
 
      if(ans==m)r=mid;
      else l=mid;
    }
    printf("%.8f\n",l);
  }
}
accuracy: 1
time_ms: 80
memory_kb: 3476
final_rank: 11

code_snippet: #include<bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
#define MAX_V 1000
#define INF 1<<29
using namespace std;
 
 
//  geometry
 
 
typedef double D;
typedef complex<D> P;
const D EPS = 1e-9;
#define X real()
#define Y imag()
 
//  flow
 
 
struct edge{int to,cap,rev;};
vector<edge>G[MAX_V];
int level[MAX_V];
int iter[MAX_V];
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});
}
void bfs(int s){
  memset(level,-1,sizeof(level));
  queue<int>q;
  level[s]=0;
  q.push(s);
  while(!q.empty()){
    int v=q.front();q.pop();
    for(int i=0;i<G[v].size();i++){
      edge &e=G[v][i];
      if(e.cap>0&&level[e.to]<0){
    level[e.to]=level[v]+1;
    q.push(e.to);
      }
    }
  }
}
int dfs(int v,int t,int f){
  if(v==t)return f;
  for(int &i=iter[v];i<G[v].size();i++){
    edge &e=G[v][i];
    if(e.cap>0&&level[v]<level[e.to]){
      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;
  while(1){
    bfs(s);
    if(level[t]<0)return flow;
    memset(iter,0,sizeof(iter));
    int f;
    while((f=dfs(s,t,INF))>0){
      flow+=f;
    }
  }
}
 
void init(){
  r(i,MAX_V)G[i].clear();
  r(i,MAX_V)level[i]=0;
  r(i,MAX_V)iter[i]=0;
}
 
int n,m;
double xx,yy,vv[101];
double di[101][101];
vector<P>v,vp;
 
int main(){
  while(cin>>n>>m,n){
    vp.clear();
    v.clear();
    r(i,n){
      cin>>xx>>yy>>vv[i];
      v.push_back(P(xx,yy));
    }
    r(i,m){
      cin>>xx>>yy;
      P pt=P(xx,yy);
      vp.push_back(pt);
    }
    r(i,n)r(j,m)di[i][j]=abs(vp[j]-v[i])/vv[i];
    D l=0,r=1e9;
    r(i,145){
       
      init();
      D mid=(l+r)/2;
       
      r(j,n)r(k,m)if(di[j][k]<=mid){
        add_edge(j+1,k+201,1);
      }
      r(j,n)add_edge(0,j+1,1);
      r(j,m)add_edge(j+201,500,1);
 
      int ans=max_flow(0,500);
 
      if(ans==m)r=mid;
      else l=mid;
    }
    printf("%.8f\n",l);
  }
}
accuracy: 1
time_ms: 150
memory_kb: 3568
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
struct Match {
  vector<vector<Int> > G;
  int V;
  vector<int> match, used;
  Match(){}
  Match(int V):V(V), G(V), match(V, -1), used(V, 0){}
  void add_edge(int u, int v) {
    G[u].push_back(v);
    G[v].push_back(u);
  }
  bool dfs(int v) {
    used[v] = true;
    for(int i = 0; i < (int)G[v].size(); i++) {
      int u = G[v][i], w = match[u];
      if(w<0 || (!used[w]&&dfs(w))) {
	match[v] = u;
	match[u] = v;
	return true;
      }
    }
    return false;
  }
  int matching() {
    int res = 0;
    for(int v = 0; v < V; v++) {
      if(match[v] < 0) {
	fill(used.begin(), used.end(), 0);
	if(dfs(v)) {
	  res++;
	}
      }
    }
    return res;
  }
};
double tx[101], ty[101], v[101];
double bx[101], by[101];
double sq(double x) {
  return x*x;
}
signed main(){
  int N, M;
  while(cin >> N >> M, N+M) {
    for(int i = 0; i < N; i++) {
      cin >> tx[i] >> ty[i] >> v[i];
    }
    for(int i = 0; i < M; i++) {
      cin >> bx[i] >> by[i];
    }
    assert(N >= M);
    double lb = 0, ub = 1e9;
    for(int k = 0; k < 200; k++) {
      double mb = (lb+ub)/2;
      Match G(N+M);
      for(int i = 0; i < N; i++) {
	for(int j = 0; j < M; j++) {
	  if(sqrt(sq(tx[i]-bx[j])+sq(ty[i]-by[j])) <= v[i]*mb) {
	    G.add_edge(i, j+N);
	  }
	}
      }
      if(G.matching() == M) ub = mb;
      else lb = mb;
    }
    printf("%.8f\n", ub);
  }

  return 0;
}
accuracy: 1
time_ms: 410
memory_kb: 3376
final_rank: 15

code_snippet: #include<bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
#define MAX_V 1000
#define INF 1<<29
using namespace std;


//  geometry


typedef double D;
typedef complex<D> P;
const D EPS = 1e-9;
#define X real()
#define Y imag()

//  flow


struct edge{int to,cap,rev;};
vector<edge>G[MAX_V];
int level[MAX_V];
int iter[MAX_V];
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});
}
void bfs(int s){
  memset(level,-1,sizeof(level));
  queue<int>q;
  level[s]=0;
  q.push(s);
  while(!q.empty()){
    int v=q.front();q.pop();
    for(int i=0;i<G[v].size();i++){
      edge &e=G[v][i];
      if(e.cap>0&&level[e.to]<0){
	level[e.to]=level[v]+1;
	q.push(e.to);
      }
    }
  }
}
int dfs(int v,int t,int f){
  if(v==t)return f;
  for(int &i=iter[v];i<G[v].size();i++){
    edge &e=G[v][i];
    if(e.cap>0&&level[v]<level[e.to]){
      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;
  while(1){
    bfs(s);
    if(level[t]<0)return flow;
    memset(iter,0,sizeof(iter));
    int f;
    while((f=dfs(s,t,INF))>0){
      flow+=f;
    }
  }
}

void init(){
  r(i,MAX_V)G[i].clear();
  r(i,MAX_V)level[i]=0;
  r(i,MAX_V)iter[i]=0;
}

int n,m;
double xx,yy,vv[101];
double di[101][101];
vector<P>v,vp;

int main(){
  while(cin>>n>>m,n){
    vp.clear();
    v.clear();
    r(i,n){
      cin>>xx>>yy>>vv[i];
      v.push_back(P(xx,yy));
    }
    r(i,m){
      cin>>xx>>yy;
      P pt=P(xx,yy);
      vp.push_back(pt);
    }
    r(i,n)r(j,m)di[i][j]=abs(vp[j]-v[i])/vv[i];
    D l=0,r=1e9;
    r(i,145){
      
      init();
      D mid=(l+r)/2;
      
      r(j,n)r(k,m)if(di[j][k]<=mid){
        add_edge(j+1,k+201,1);
      }
      r(j,n)add_edge(0,j+1,1);
      r(j,m)add_edge(j+201,500,1);

      int ans=max_flow(0,500);

      if(ans==m)r=mid;
      else l=mid;
    }
    printf("%.8f\n",l);
  }
}
accuracy: 1
time_ms: 150
memory_kb: 3448
final_rank: 12

code_snippet: #include "bits/stdc++.h"
using namespace std;
#ifdef _DEBUG
#include "dump.hpp"
#else
#define dump(...)
#endif

//#define int long long
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(c) begin(c),end(c)
const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)(1e9) + 7;
template<class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template<class T> bool chmin(T &a, const T &b) { if (b < a) { a = b; return true; } return false; }

struct BipartiteMatching {
	int n;
	vector<vector<int>> g;
	vector<int> match;
	vector<int> used;
	BipartiteMatching(int n) : n(n), g(n), match(n), used(n) {}
	void addEdge(int u, int v) {
		g[u].emplace_back(v);
		g[v].emplace_back(u);
	}
	int maximumMatching() {
		int cnt = 0;
		fill(match.begin(), match.end(), -1);
		for (int v = 0; v < n; v++) {
			if (match[v] == -1) {
				fill(used.begin(), used.end(), false);
				if (augment(v)) cnt++;
			}
		}
		return cnt;
	}
	bool augment(int v) {
		used[v] = true;
		for (int u : g[v]) {
			int w = match[u];
			if (w == -1 || (!used[w] && augment(w))) {
				match[v] = u;
				match[u] = v;
				return true;
			}
		}
		return false;
	}
};

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	for (int N, M; cin >> N >> M&&N;) {
		using Edge = tuple<double, int, int>;
		vector<Edge> es;
		vector<int> x(N), y(N), v(N); rep(i, 0, N) {
			cin >> x[i] >> y[i] >> v[i];
		}
		vector<int> bx(M), by(M); rep(i, 0, M) {
			cin >> bx[i] >> by[i];
		}
		rep(i, 0, N)rep(j, 0, M) {
			double d = sqrt((x[i] - bx[j])*(x[i] - bx[j]) + (y[i] - by[j])*(y[i] - by[j])) / v[i];
			es.emplace_back(d, i, j);
		}
		sort(all(es));

		auto f = [&](int x) {
			BipartiteMatching bm(N + M);
			rep(i, 0, x + 1) {
				double d; int a, b; tie(d, a, b) = es[i];
				bm.addEdge(a, N + b);
			}
			return bm.maximumMatching() == M;
		};
		auto binarySearch = [&](int ng, int ok) {
			if (f(ng))return ng;
			while (ng + 1 < ok) {
				int m = (ng + ok) / 2;
				if (f(m))
					ok = m;
				else
					ng = m;
			}
			return ok;
		};

		int ok = binarySearch(0, es.size() - 1);
		cout << fixed << setprecision(10);
		cout << get<0>(es[ok]) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3540
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

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

const int MAX_V = 222;
const int F_INF = 19191919;
vector<edge> G[MAX_V];
int lv[MAX_V],it[MAX_V];

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

void dinic_bfs(int s){
    memset(lv,-1,sizeof(lv));
    queue<int> que;
    lv[s]=0;
    que.push(s);
    while(!que.empty()){
        int v = que.front(); que.pop();
        rep(i,G[v].size()){
            edge &e = G[v][i];
            if(e.cap>0 && lv[e.to]<0){
                lv[e.to] = lv[v]+1;
                que.push(e.to);
            }
        }
    }
}

int dinic_dfs(int v, int t, int f){
    if(v==t) return f;
    for(int &i=it[v]; i<G[v].size(); ++i){
        edge &e = G[v][i];
        if(e.cap>0 && lv[v]<lv[e.to]){
            int d = dinic_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;
    while(1){
        dinic_bfs(s);
        if(lv[t]<0) return flow;
        memset(it,0,sizeof(it));
        int f;
        while((f=dinic_dfs(s,t,F_INF))>0) flow+=f;
    }
}

struct Point{ int x,y,v; };

inline double dist(const Point &p, const Point &q)
{
    return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y));
}

using pi = pair<int,int>;
using pd = pair<double,pi>;

int main()
{
    int n,m;
    while(scanf(" %d %d", &n, &m),n)
    {
        rep(i,MAX_V) G[i].clear();
        int S = n+m, T = S+1;

        vector<Point> t(n),b(m);
        rep(i,n) scanf(" %d %d %d", &t[i].x, &t[i].y, &t[i].v);
        rep(i,m) scanf(" %d %d", &b[i].x, &b[i].y);

        vector<pd> e;
        rep(i,n)rep(j,m) e.pb({dist(t[i],b[j])/t[i].v,pi(i,j)});
        sort(all(e));

        rep(i,n) add_edge(S,i,1);
        rep(i,m) add_edge(n+i,T,1);

        int idx = 0;
        int f = 0;
        int E = e.size();
        while(idx<E)
        {
            int u = e[idx].se.fi, v = n+e[idx].se.se;
            add_edge(u,v,1);
            f += max_flow(S,T);
            if(f==m) break;
            ++idx;
        }

        assert(idx<E);
        printf("%.10f\n", e[idx].fi);
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3816
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;

using graph = std::vector<std::vector<int>>;

bool dfs(graph const& g, int v, std::vector<int>& match, std::vector<bool>& used) {
    used[v] = true;
    for(auto u : g[v]) {
        int w = match[u];
        if(w < 0 || !used[w] && dfs(g, w, match, used)) {
            match[v] = u;
            match[u] = v;
            return true;
        }
    }
    return false;
}

int bipartite_matching(graph const& g) {
    const int V = g.size();
    std::vector<int> match(V, -1);
    std::vector<bool> used(V);
    int res = 0;
    for(int v=0; v<V; ++v) {
        if(match[v] < 0) {
            std::fill(used.begin(), used.end(), false);
            if(dfs(g, v, match, used)) {
                ++res;
            }
        }
    }
    return res;
}

constexpr double eps = 1e-8;

int main() {
    int N, M;
    while(cin >> N >> M, N) {
        vector<double> tx(N), ty(N), v(N);
        for(int i=0; i<N; ++i) {
            cin >> tx[i] >> ty[i] >> v[i];
        }
        vector<double> bx(M), by(M);
        for(int i=0; i<M; ++i) {
            cin >> bx[i] >> by[i];
        }
        double lb = -1, ub = 1e9;
        while(abs(ub - lb) > eps) {
            double m = (ub + lb) / 2;
            graph g(N+M);
            for(int i=0; i<N; ++i) {
                for(int j=0; j<M; ++j) {
                    if(hypot(tx[i]-bx[j], ty[i]-by[j]) - eps <= v[i] * m) {
                        g[i].push_back(N+j);
                        g[N+j].push_back(i);
                    }
                }
            }
            if(bipartite_matching(g) == M) {
                ub = m;
            } else {
                lb = m;
            }
        }
        cout << fixed << setprecision(10) << ub << endl;
    }
}
accuracy: 1
time_ms: 140
memory_kb: 3396
final_rank: 8

code_snippet: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);i++)
using namespace std;

vector<int>E[100];
bool used[200];
int match[200];

bool dfs(int u) {
	used[u] = true;
	for (int v : E[u]) {
		int w = match[v];
		if (w == -1 || (!used[w] && dfs(w))) {
			match[u] = v; match[v] = u;
			return true;
		}
	}
	return false;
}
int x[100], y[100], z[100], a[100], b[100];
double d[100][100];
int main() {
	int n, m;
	while (scanf("%d%d", &n, &m), n) {
		rep(i, n)scanf("%d%d%d", &x[i], &y[i], &z[i]);
		rep(i, m)scanf("%d%d", &a[i], &b[i]);
		rep(i, n)rep(j, m)d[i][j] = hypot(x[i] - a[j], y[i] - b[j]) / z[i];
		double l = 0, r = 14143;
		rep(i, 41) {
			double t = (l + r) / 2;
			rep(j, n) {
				E[j].clear();
				rep(k, m) {
					if (d[j][k] <= t)E[j].push_back(n + k);
				}
			}
			int cnt = 0;
			memset(match, -1, sizeof(match));
			rep(j, n) {
				if (match[j] == -1) {
					memset(used, 0, sizeof(used));
					cnt += dfs(j);
				}
			}
			if (cnt == m)r = t;
			else l = t;
		}
		printf("%.14lf\n", l);
	}
}
accuracy: 1
time_ms: 30
memory_kb: 3372
final_rank: 5

code_snippet: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);i++)
using namespace std;

vector<int>E[100];
bool used[200];
int match[200];

bool dfs(int u) {
	used[u] = true;
	for (int v : E[u]) {
		int w = match[v];
		if (w == -1 || (!used[w] && dfs(w))) {
			match[u] = v; match[v] = u;
			return true;
		}
	}
	return false;
}
int x[100], y[100], z[100], a[100], b[100];
double d[100][100];
int main() {
	int n, m;
	while (scanf("%d%d", &n, &m), n) {
		rep(i, n)scanf("%d%d%d", &x[i], &y[i], &z[i]);
		rep(i, m)scanf("%d%d", &a[i], &b[i]);
		rep(i, n)rep(j, m)d[i][j] = hypot(x[i] - a[j], y[i] - b[j]) / z[i];
		double l = 0, r = 14143;
		rep(i, 42) {
			double t = (l + r) / 2;
			rep(j, n) {
				E[j].clear();
				rep(k, m) {
					if (d[j][k] <= t)E[j].push_back(n + k);
				}
			}
			int cnt = 0;
			memset(match, -1, sizeof(match));
			rep(j, n) {
				if (match[j] == -1) {
					memset(used, 0, sizeof(used));
					cnt += dfs(j);
				}
			}
			if (cnt == m)r = t;
			else l = t;
		}
		printf("%.14lf\n", l);
	}
}
accuracy: 1
time_ms: 30
memory_kb: 3380
final_rank: 6

code_snippet: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);i++)
using namespace std;

vector<int>E[100];
bool used[200];
int match[200];

bool dfs(int u) {
	used[u] = true;
	for (int v : E[u]) {
		int w = match[v];
		if (w == -1 || (!used[w] && dfs(w))) {
			match[u] = v; match[v] = u;
			return true;
		}
	}
	return false;
}
int x[100], y[100], z[100], a[100], b[100];
double d[100][100];
int main() {
	int n, m;
	while (scanf("%d%d", &n, &m), n) {
		rep(i, n)scanf("%d%d%d", &x[i], &y[i], &z[i]);
		rep(i, m)scanf("%d%d", &a[i], &b[i]);
		rep(i, n)rep(j, m)d[i][j] = hypot(x[i] - a[j], y[i] - b[j]) / z[i];
		double l = 0, r = 15000;
		rep(i, 42) {
			double t = (l + r) / 2;
			rep(j, n) {
				E[j].clear();
				rep(k, m) {
					if (d[j][k] <= t)E[j].push_back(n + k);
				}
			}
			int cnt = 0;
			memset(match, -1, sizeof(match));
			rep(j, n) {
				if (match[j] == -1) {
					memset(used, 0, sizeof(used));
					cnt += dfs(j);
				}
			}
			if (cnt == m)r = t;
			else l = t;
		}
		printf("%.14lf\n", l);
	}
}
accuracy: 1
time_ms: 30
memory_kb: 3252
final_rank: 2

code_snippet: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);i++)
using namespace std;

vector<int>E[100];
bool used[200];
int match[200];

bool dfs(int u) {
	used[u] = true;
	for (int v : E[u]) {
		int w = match[v];
		if (w == -1 || (!used[w] && dfs(w))) {
			match[u] = v; match[v] = u;
			return true;
		}
	}
	return false;
}
int x[100], y[100], z[100], a[100], b[100];
double d[100][100];
int main() {
	int n, m;
	while (scanf("%d%d", &n, &m), n) {
		rep(i, n)scanf("%d%d%d", &x[i], &y[i], &z[i]);
		rep(i, m)scanf("%d%d", &a[i], &b[i]);
		rep(i, n)rep(j, m)d[i][j] = hypot(x[i] - a[j], y[i] - b[j]) / z[i];
		double l = 0, r = 15000;
		rep(i, 43) {
			double t = (l + r) / 2;
			rep(j, n) {
				E[j].clear();
				rep(k, m) {
					if (d[j][k] <= t)E[j].push_back(n + k);
				}
			}
			int cnt = 0;
			memset(match, -1, sizeof(match));
			rep(j, n) {
				if (match[j] == -1) {
					memset(used, 0, sizeof(used));
					cnt += dfs(j);
				}
			}
			if (cnt == m)r = t;
			else l = t;
		}
		printf("%.14lf\n", l);
	}
}
accuracy: 1
time_ms: 30
memory_kb: 3252
final_rank: 2

code_snippet: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);i++)
using namespace std;

vector<int>E[100];
bool used[200];
int match[200];

bool dfs(int u) {
	used[u] = true;
	for (int v : E[u]) {
		int w = match[v];
		if (w == -1 || (!used[w] && dfs(w))) {
			match[u] = v; match[v] = u;
			return true;
		}
	}
	return false;
}
int x[100], y[100], z[100], a[100], b[100];
double d[100][100];
int main() {
	int n, m;
	while (scanf("%d%d", &n, &m), n) {
		rep(i, n)scanf("%d%d%d", &x[i], &y[i], &z[i]);
		rep(i, m)scanf("%d%d", &a[i], &b[i]);
		rep(i, n)rep(j, m)d[i][j] = hypot(x[i] - a[j], y[i] - b[j]) / z[i];
		double l = 0, r = 15000;
		rep(i, 45) {
			double t = (l + r) / 2;
			rep(j, n) {
				E[j].clear();
				rep(k, m) {
					if (d[j][k] <= t)E[j].push_back(n + k);
				}
			}
			int cnt = 0;
			memset(match, -1, sizeof(match));
			rep(j, n) {
				if (match[j] == -1) {
					memset(used, 0, sizeof(used));
					cnt += dfs(j);
				}
			}
			if (cnt == m)r = t;
			else l = t;
		}
		printf("%.14lf\n", l);
	}
}
accuracy: 1
time_ms: 40
memory_kb: 3324
final_rank: 4