1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| using namespace std; using ld = long double; using ll = long long;
const int maxn = 3e5 + 5; const ll inf = 4e18;
struct Point { ll x, y; friend Point operator - ( const Point A, const Point B ) { return { A.x - B.x, A.y - B.y }; } };
int n, m; ld vy; pair<Point, Point> seg[maxn];
ld getx( auto s, ld y, bool right ) { auto [A, B] = s; if( A.y == B.y ) { if( right ) return max( A.x, B.x ); else return min( A.x, B.x ); } return A.x + (ld)( B.x - A.x ) * ( y - A.y ) / ( B.y - A.y ); }
ld get( int i, int j ) { auto [A1, A2] = seg[i]; auto [B1, B2] = seg[j]; ll l = max( min( A1.y, A2.y ), min( B1.y, B2.y ) ); ll r = min( max( A1.y, A2.y ), max( B1.y, B2.y ) ); if( l <= r ) { ld y = ( l + r ) / 2.0; ld xr = getx( seg[i], y, 1 ); ld xl = getx( seg[j], y, 0 ); if( xr >= xl ) return inf; }
Point a[2] = { A1, A2 }; Point b[2] = { B1, B2 };
ld res = 0; for( int x = 0; x < 2; ++ x ) { for( int y = 0; y < 2; ++ y ) { if( a[x].y == b[y].y ) continue; ll dx = max( 0ll, a[x].x - b[y].x ); ll dy = abs( a[x].y - b[y].y ); res = max( res, (ld)vy * dx / dy ); } } return res; }
ld getw( int u, int v ) { if( u == 0 && v == n + 1 ) return 0; if( u == 0 ) { ll lx = min( seg[v].first.x, seg[v].second.x ); return lx == -m ? inf : 0; } if( v == n + 1 ) { ll rx = max( seg[u].first.x, seg[u].second.x ); return rx == m ? inf : 0; } return get( u, v ); }
struct State { int u; ld d; bool operator < ( const State &a ) const { return d < a.d; } }; ld dis[maxn << 1];
void dijkstra( int S, int T ) { fill( dis + 1, dis + T + 1, -1 ); dis[S] = inf; priority_queue<State> pq; pq.push({ S, inf }); while( !pq.empty( ) ) { auto [u, d] = pq.top( ); pq.pop( ); if( dis[u] != d ) continue; if( u == T ) break; for( int v = 1; v <= T; ++ v ) { if( u == v ) continue; ld w = getw( u, v ); ld nd = min( dis[u], w ); if( nd > dis[v] ) { dis[v] = nd; pq.push({ v, nd }); } } } }
void solve( ) { n = read( ), m = read( ); int _vy = read( ); vy = 1.0 * _vy;
for( int i = 1; i <= n; ++ i ) { int x1 = read( ), y1 = read( ); int x2 = read( ), y2 = read( ); seg[i] = { { x1, y1 }, { x2, y2 } }; }
int S = 0, T = n + 1; dijkstra( S, T ); if( dis[T] == inf ) { cout << -1 << '\n'; } else { cout << fixed << setprecision( 15 ) << dis[T] << '\n'; } }
|