码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ2596 [Wc2007]疯狂赛车

时间:2015-02-17 19:54:58      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:

写了一上午谁叫你智商低呢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 }
View Code

 

BZOJ2596 [Wc2007]疯狂赛车

标签:

原文地址:http://www.cnblogs.com/rausen/p/4295413.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!