#include #include #include #include #include #include #include #include using namespace std; using F = int; struct S { const int v; // neighbour const int r; // index of the reverse edge F f; // current flow const F cap; // capacity S(int v, int ri, F c) : v(v), r(ri), f(0), cap(c) {} }; struct FlowGraph : vector> { FlowGraph(size_t n) : vector>(n) {} void add_edge(int u, int v, F c = 1) { auto &t = *this; t[u].emplace_back(v, t[v].size(), c); t[v].emplace_back(u, t[u].size() - 1, 0); } }; struct Dinic { FlowGraph &edges; int V, s, t; vector l; vector::iterator> its; // levels and iterators Dinic(FlowGraph &edges, int s, int t) : edges(edges), V(edges.size()), s(s), t(t), l(V, -1), its(V) {} int augment(int u, F c) { // we reuse the same iterators if(u == t) return c; for(auto &i = its[u]; i != edges[u].end(); i++) { auto &e = *i; if(e.cap > e.f && l[u] < l[e.v]) { auto d = augment(e.v, min(c, e.cap - e.f)); if(d > 0) { e.f += d; edges[e.v][e.r].f -= d; return d; } } } return 0; } int run() { int flow = 0, f; while(true) { fill(l.begin(), l.end(), -1); l[s] = 0; // recalculate the layers queue q; q.push(s); while(!q.empty()) { auto u = q.front(); q.pop(); for(auto &&e : edges[u]) if(e.cap > e.f && l[e.v] < 0) l[e.v] = l[u] + 1, q.push(e.v); } if(l[t] < 0) return flow; for(int u = 0; u < V; ++u) its[u] = edges[u].begin(); while((f = augment(s, 1e9)) > 0) flow += f; } } }; struct P { int x, y; }; int dist(P &l, P &r) { return (l.x - r.x) * (l.x - r.x) + (l.y - r.y) * (l.y - r.y); } struct D { int b, r, dist; bool operator<(const D &x) { return tie(dist, b, r) < tie(x.dist, x.b, x.r); } }; int main() { int n, b, r; cin >> n >> b >> r; vector

bs(b), rs(r); for(auto &p : bs) cin >> p.x >> p.y; for(auto &p : rs) cin >> p.x >> p.y; vector dists; dists.reserve(b * r); for(int i = 0; i < b; ++i) for(int j = 0; j < r; ++j) dists.push_back({i, j, dist(bs[i], rs[j])}); sort(dists.begin(), dists.end()); // binary search (using iterators :D) the right distance auto be = dists.begin(), e = dists.end(); while(be < e) { FlowGraph g(b + r + 2); int s = b + r, t = b + r + 1; for(int i = 0; i < b; ++i) g.add_edge(s, i); for(int j = 0; j < r; ++j) g.add_edge(b + j, t); auto m = be + (e - be + 1) / 2; for(auto x = dists.begin(); x != m; ++x) g.add_edge(x->b, b + x->r); if(Dinic(g, s, t).run() > r + b - n) e = m - 1; else be = m; } cout << fixed << setprecision(11) << sqrt(be->dist) << endl; return 0; }