写了一上午谁叫你智商低呢2333
Orz ydc虽然WC考跪了没进15人队
计算几何题真烦【摔
1 /************************************************************** 2 Problem: 2596 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:2256 ms 7 Memory:159952 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cmath> 12 #include <cstring> 13 #include <algorithm> 14 #include <vector> 15 #include <queue> 16 17 using namespace std; 18 typedef double lf; 19 const lf eps = 1e-10; 20 const int N = 3000005; 21 22 inline int read() { 23 int x = 0, sgn = 1; 24 char ch = getchar(); 25 while (ch < ‘0‘ || ‘9‘ < ch) { 26 if (ch == ‘-‘) sgn = -1; 27 ch = getchar(); 28 } 29 while (‘0‘ <= ch && ch <= ‘9‘) { 30 x = x * 10 + ch - ‘0‘; 31 ch = getchar(); 32 } 33 return sgn * x; 34 } 35 36 inline lf sqr(lf x) { 37 return x * x; 38 } 39 40 inline int dcmp(lf x) { 41 return fabs(x) <= eps ? 0 : (x > eps ? 1 : -1); 42 } 43 44 struct point { 45 lf x, y; 46 point() {} 47 point(lf _x, lf _y) : x(_x), y(_y) {} 48 49 inline point operator + (point p) { 50 return point(x + p.x, y + p.y); 51 } 52 inline point operator - (point p) { 53 return point(x - p.x, y - p.y); 54 } 55 inline lf operator * (point p) { 56 return x * p.y - y * p.x; 57 } 58 inline lf operator % (point p) { 59 return x * p.x + y * p.y; 60 } 61 inline point operator * (lf a) { 62 return point(x * a, y * a); 63 } 64 inline point operator / (lf a) { 65 return point(x / a, y / a); 66 } 67 68 inline bool operator < (const point &p) const { 69 return dcmp(x - p.x) == 0 ? dcmp(y - p.y) < 0 : dcmp(x - p.x) < 0; 70 } 71 inline bool operator != (const point &p) const { 72 return dcmp(x - p.x) || dcmp(y - p.y); 73 } 74 inline bool operator == (const point &p) const { 75 return !dcmp(x - p.x) && !dcmp(y - p.y); 76 } 77 78 friend inline lf dis2(point p) { 79 return sqr(p.x) + sqr(p.y); 80 } 81 friend inline lf dis(point p) { 82 return sqrt(dis2(p)); 83 } 84 friend inline lf dis(point p, point a, point b) { 85 return fabs(((p - a) * (p - b)) / dis(b - a)); 86 } 87 friend inline point projection(point p, point a, point b) { 88 point c = b - a; 89 lf t = -((a - p) % c) / (c % c); 90 return a + c * t; 91 } 92 friend inline bool on_seg(point p, point a, point b) { 93 return dcmp(p.x - a.x) * dcmp(p.x - b.x) <= 0 && 94 dcmp(p.y - a.y) * dcmp(p.y - b.y) <= 0; 95 } 96 } p[N]; 97 98 struct edge { 99 int next, to; 100 lf v; 101 edge() {} 102 edge(int _n, int _t, lf _v) : next(_n), to(_t), v(_v) {} 103 } e[N]; 104 105 struct heap_node { 106 lf v; 107 int to; 108 heap_node() {} 109 heap_node(lf _v, int _t) : v(_v), to(_t) {} 110 111 inline bool operator < (const heap_node &a) const { 112 return v > a.v; 113 } 114 }; 115 116 int n, cnt; 117 lf va, vb, Dis[N]; 118 int first[N], tot; 119 priority_queue <heap_node> h; 120 121 inline void add_edge(int x, int y, lf z) { 122 e[++tot] = edge(first[x], y, z); 123 first[x] = tot; 124 } 125 126 inline void Add_Edges(int x, int y, lf z) { 127 add_edge(x, y, z); 128 add_edge(y, x, z); 129 } 130 131 vector <point> E; 132 int pos[N]; 133 134 void build_graph() { 135 int i, j, id; 136 lf H, D; 137 point Pro, v, P, p1, p2; 138 for (i = 1; i <= n; ++i) { 139 E.clear(); 140 p1 = p[i], p2 = p[i + 1]; 141 for (j = 1; j <= n + 1; ++j) 142 if (p[j] != p1 && p[j] != p2) { 143 H = dis(p[j], p1, p2), D = vb * H / sqrt(sqr(va) - sqr(vb)); 144 Pro = projection(p[j], p1, p2), v = (p2 - p1) / dis(p2 - p1); 145 P = Pro + v * D; 146 if (on_seg(P, p1, p2)) E.push_back(P); 147 P = Pro - v * D; 148 if (on_seg(P, p1, p2)) E.push_back(P); 149 } 150 151 E.push_back(p1), E.push_back(p2); 152 sort(E.begin(), E.end()); 153 int Cnt = unique(E.begin(), E.end()) - E.begin(); 154 if (E[0] == p1) 155 pos[0] = i, pos[Cnt - 1] = i + 1; 156 else 157 pos[0] = i + 1, pos[Cnt - 1] = i; 158 for (j = 1; j < Cnt - 1; ++j) 159 pos[j] = ++cnt; 160 for (j = 0; j < Cnt - 1; ++j) 161 Add_Edges(pos[j], pos[j + 1], dis(E[j] - E[j + 1]) / va); 162 163 for (j = 1; j <= n + 1; ++j) 164 if (p[j] != p1 && p[j] != p2) { 165 H = dis(p[j], p1, p2), D = vb * H / sqrt(sqr(va) - sqr(vb)); 166 Pro = projection(p[j], p1, p2), v = (p2 - p1) / dis(p2 - p1); 167 P = Pro + v * D; 168 if (on_seg(P, p1, p2)) { 169 id = lower_bound(E.begin(), E.end(), P) - E.begin(); 170 Add_Edges(pos[id], j, dis(P - p[j]) / vb); 171 } 172 P = Pro - v * D; 173 if (on_seg(P, p1, p2)) { 174 id = lower_bound(E.begin(), E.end(), P) - E.begin(); 175 Add_Edges(pos[id], j, dis(P - p[j]) / vb); 176 } 177 } 178 } 179 } 180 181 #define y e[x].to 182 inline void add_to_heap(int p) { 183 int x; 184 for (x = first[p]; x; x = e[x].next) 185 if (!dcmp(Dis[y] + 1.0)) 186 h.push(heap_node(e[x].v + Dis[p], y)); 187 } 188 #undef y 189 190 void Dijkstra(int S) { 191 int p; 192 for (p = 1; p <= cnt; ++p) 193 Dis[p] = -1.0; 194 while (!h.empty()) h.pop(); 195 Dis[S] = 0, add_to_heap(S); 196 while (!h.empty()) { 197 while (dcmp(Dis[h.top().to] + 1.0) && !h.empty()) h.pop(); 198 if (h.empty()) break; 199 p = h.top().to; 200 Dis[p] = h.top().v; 201 if (p == n + 1) return; 202 h.pop(); 203 add_to_heap(p); 204 } 205 } 206 207 int main() { 208 int i, j, x, y; 209 n = read(); 210 scanf("%lf%lf", &va, &vb); 211 p[1] = point(0, 0); 212 for (i = 1; i <= n; ++i) { 213 x = read(), y = read(); 214 p[i + 1] = point(x, y); 215 } 216 for (i = 1; i <= n + 1; ++i) 217 for (j = 1; j <= n + 1; ++j) 218 if (i != j) 219 add_edge(i, j, dis(p[i] - p[j]) / vb); 220 cnt = n + 1; 221 build_graph(); 222 Dijkstra(1); 223 printf("%lf\n", Dis[n + 1]); 224 return 0; 225 }
时间: 2024-10-08 14:07:07