POJ 1556 The Doors (Computational ry + Shortest Path)
The problem is that if two points can be reached, even one edge can be reached. You can use the intersection of line segments to determine whether the edge can be reached. Finally, you can find the shortest path.
Code:
# Include
# Include
# Include
# Include
Using namespace std; # include
# Include
# Include
# Include using namespace std; struct Point {double x, y; Point () {} Point (double x, double y) {this-> x = x; this-> y = y;} void read () {scanf ("% lf", & x, & y) ;}; typedef Point Vector; vector operator-(Vector A, Vector B) {return Vector (. x-B. x,. y-B. y);} const double eps = 1e-8; int dcmp (double x) {if (fabs (x) <eps) return 0; else return x <0? -1: 1;} double Cross (Vector A, Vector B) {return. x * B. y-. y * B. x;} // Cross Product // The bool SegmentProperIntersection2 (Point a1, Point a2, Point b1, Point b2) {double c1 = Cross (a2-a1, b1-a1), c2 = Cross (a2-a1, b2-a1), c3 = Cross (b2-b1, a1-b1), c4 = Cross (b2-b1, a2-b1); return max (a1.x, a2.x)> = min (b1.x, b2.x) & max (b1.x, b2.x)> = min (a1.x, a2.x) & max (a1.y, a2.y)> = min (b1.y, b2.y) & max (b1.y, b2.y)> = min (a1.y, a2.y) & dcmp (c1) * dcmp (c2) <= 0 & dcmp (c3) * dcmp (c4) <= 0;} const int N = 25; int n; struct Ban {Point p [4]; void read () {double a, y [4]; scanf ("% lf", & a); for (int I = 0; I <4; I ++) {scanf ("% lf", & y [I]); p [I] = Point (, y [I]) ;}}} B [N]; struct Edge {int u, v; double w; Edge () {} Edge (int u, int v, double w) {this-> u = u; this-> v = v; this-> w = w ;}}; vector
G [N * 4]; double dist (Point a, Point B) {double dx =. x-B. x; double dy =. y-B. y; return sqrt (dx * dx + dy * dy);} void add_edge (int u, int v, double d) {g [u]. push_back (Edge (u, v, d); g [v]. push_back (Edge (v, u, d);} bool judge (int l, int r, Point aa, Point bb) {for (int I = l; I <= r; I ++) {if (! SegmentProperIntersection2 (aa, bb, B [I]. p [0], B [I]. p [1]) &! SegmentProperIntersection2 (aa, bb, B [I]. p [2], B [I]. p [3]) return false;} return true;} double d [N * 4]; int vis [N * 4]; double spfa (int s, int t) {memset (vis, 0, sizeof (vis); queue
Q; for (int I = 0; I <= t; I ++) d [I] = 1e20; d [0] = 0; vis [0] = 1; q. push (0); while (! Q. empty () {int u = Q. front (); Q. pop (); vis [u] = 0; for (int I = 0; I <g [u]. size (); I ++) {int v = g [u] [I]. v; double w = g [u] [I]. w; if (d [u] + w <d [v]) {d [v] = d [u] + w; if (! Vis [v]) {vis [v] = 1; Q. push (v) ;}}} return d [t] ;}int main () {while (~ Scanf ("% d", & n) & n! =-1) {for (int I = 0; I <= n * 4 + 1; I ++) g [I]. clear (); for (int I = 0; I <n; I ++) B [I]. read (); if (judge (0, n-1, Point (0, 5), Point (10, 5) add_edge (0, n * 4 + 1, 10); for (int I = 0; I <n; I ++) {for (int j = 0; j <4; j ++) {if (judge (0, I-1, Point (0, 5), B [I]. p [j]) add_edge (0, I * 4 + j + 1, dist (Point (0, 5), B [I]. p [j]); if (judge (I + 1, n-1, B [I]. p [j], Point (10, 5) add_edge (n * 4 + 1, I * 4 + j + 1, dist (Point (10, 5 ), B [I]. p [j]); for (int k = I + 1; k <n; k ++) {for (int x = 0; x <4; x ++) {if (judge (I + 1, k-1, B [I]. p [j], B [k]. p [x]) add_edge (I * 4 + j + 1, k * 4 + x + 1, dist (B [I]. p [j], B [k]. p [x]) ;}}} printf ("%. 2f \ n ", spfa (0, n * 4 + 1);} return 0 ;}