#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; static const double EPS = 1e-8; static const double PI = 4.0 * atan(1.0); static const double PI2 = 8.0 * atan(1.0); typedef long long ll; const double INF = 1e12; typedef complex P; double cross(const P& a, const P& b) { return imag(conj(a)*b); } double dot(const P& a, const P& b) { return real(conj(a)*b); } struct L : public vector

{ L(const P &a, const P &b) { push_back(a); push_back(b); } }; int ccw(P a, P b, P c) { b -= a; c -= a; if (cross(b, c) > 0) return +1; // counter clockwise if (cross(b, c) < 0) return -1; // clockwise if (dot(b, c) < 0) return +2; // c--a--b on line if (norm(b) < norm(c)) return -2; // a--b--c on line return 0; } bool intersectSS(const L &s, const L &t) { return ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1]) <= 0 && ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1]) <= 0; } bool intersectSP(const L &s, const P &p) { return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < EPS; // triangle inequality } P projection(const L &l, const P &p) { double t = dot(p-l[0], l[0]-l[1]) / norm(l[0]-l[1]); return l[0] + t*(l[0]-l[1]); } double distanceSP(const L &s, const P &p) { const P r = projection(s, p); if (intersectSP(s, r)) return abs(r - p); return min(abs(s[0] - p), abs(s[1] - p)); } double distanceSS(const L &s, const L &t) { if (intersectSS(s, t)) return 0; return min(min(distanceSP(s, t[0]), distanceSP(s, t[1])), min(distanceSP(t, s[0]), distanceSP(t, s[1]))); } double distanceOO(const vector& a, const vector& b) { double result = 1e100; for (vector::const_iterator it = a.begin(); it != a.end(); ++it){ for (vector::const_iterator jt = b.begin(); jt != b.end(); ++jt){ result = min(result, distanceSS(*it, *jt)); } } return result; } int main() { int W, N; cin >> W >> N; vector > objects; for (int i = 0; i < N; ++i){ vector

points; int n; cin >> n; for (int j = 0; j < n; ++j){ int x, y; cin >> x >> y; points.push_back(P(x, y)); } vector object; for (int j = 0; j < n; ++j){ object.push_back(L(points[j], points[(j + 1) % points.size()])); } objects.push_back(object); } objects.push_back(vector(1, L(P(0, 0), P(0, 1e10)))); objects.push_back(vector(1, L(P(W, 0), P(W, 1e10)))); vector > g(N + 2, vector(N + 2)); for (int i = 0; i < N + 2; ++i){ for (int j = i + 1; j < N + 2; ++j){ g[i][j] = g[j][i] = distanceOO(objects[i], objects[j]); } } priority_queue > open; open.push(make_pair(0, N)); vector memo(N + 2, 1e100); memo[N] = 0; while (!open.empty()){ const double currentCost = -open.top().first; const int currentNode = open.top().second; open.pop(); if (memo[currentNode] != currentCost){ continue; } for (int to = 0; to < N + 2; ++to){ if (memo[to] > currentCost + g[currentNode][to]){ memo[to] = currentCost + g[currentNode][to]; open.push(make_pair(-memo[to], to)); } } } printf("%.20lf\n", memo[N + 1]); }