zoukankan      html  css  js  c++  java
  • BZOJ2596 [Wc2007]疯狂赛车

    写了一上午谁叫你智商低呢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
    ", Dis[n + 1]);
    224     return 0;
    225 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    参数调优
    类路径
    《高性能MySQL》
    Hibernate操作和保存方式
    MySQL中文乱码
    数据库锁
    事务隔离级别
    分布式事务
    线程池:ThreadPoolExecutor
    系统整体测试工具
  • 原文地址:https://www.cnblogs.com/rausen/p/4295413.html
Copyright © 2011-2022 走看看