zoukankan      html  css  js  c++  java
  • POJ (线段相交 最短路) The Doors

    题意:

    一个正方形中有n道竖直的墙,每道墙上开两个门。求从左边中点走到右边中点的最短距离。

    分析:

    以起点终点和每个门的两个端点建图,如果两个点可以直接相连(即不会被墙挡住),则权值为两点间的欧几里得距离。

    然后求起点到终点的最短路即可。

      1 #include <cstdio>
      2 #include <cmath>
      3 #include <cstring>
      4 #include <vector>
      5 #include <algorithm>
      6 using namespace std;
      7 
      8 const int maxn = 50;
      9 const double INF = 1e4;
     10 const double eps = 1e-8;
     11 
     12 struct Point
     13 {
     14     double x, y;
     15     Point(double x=0, double y=0):x(x), y(y) {}
     16 }p[maxn * 4];
     17 
     18 typedef Point Vector;
     19 
     20 Point read_point()
     21 {
     22     double x, y;
     23     scanf("%lf%lf", &x, &y);
     24     return Point(x, y);
     25 }
     26 
     27 Point operator - (const Point& A, const Point& B)
     28 { return Point(A.x-B.x, A.y-B.y); }
     29 
     30 Vector operator / (const Vector& A, double p)
     31 { return Vector(A.x/p, A.y/p); }
     32 
     33 double Dot(const Vector& A, const Vector& B)
     34 { return A.x*B.x + A.y*B.y; }
     35 
     36 double Length(const Vector& A)
     37 { return sqrt(Dot(A, A)); }
     38 
     39 struct Door
     40 {
     41     double x, y1, y2, y3, y4;
     42     Door(double x=0, double y1=0, double y2=0, double y3=0, double y4=0):x(x), y1(y1), y2(y2), y3(y3), y4(y4) {}
     43 };
     44 
     45 vector<Door> door;
     46 
     47 double d[maxn * 4], w[maxn * 4][maxn * 4];
     48 bool vis[maxn * 4];
     49 int cnt;
     50 
     51 bool isOK(int a, int b)
     52 {//判断两点是否能直接到达
     53     if(p[a].x >= p[b].x) swap(a, b);
     54     for(int i = 0; i < door.size(); ++i)
     55     {
     56         if(door[i].x <= p[a].x) continue;
     57         if(door[i].x >= p[b].x) break;
     58         double k = (p[b].y-p[a].y) / (p[b].x-p[a].x);
     59         double y = p[a].y + k * (door[i].x - p[a].x);
     60         if(!(y>=door[i].y1&&y<=door[i].y2 || y>=door[i].y3&&y<=door[i].y4)) return false;
     61     }
     62     return true;
     63 }
     64 
     65 void Init()
     66 {
     67     for(int i = 0; i < cnt; ++i)
     68         for(int j = i; j < cnt; ++j)
     69             if(i == j) w[i][j] = 0;
     70             else w[i][j] = w[j][i] = INF;
     71 }
     72 
     73 int main()
     74 {
     75     //freopen("in.txt", "r", stdin);
     76 
     77     int n;
     78     while(scanf("%d", &n) == 1 && n + 1)
     79     {
     80         door.clear();
     81         memset(vis, false, sizeof(vis));
     82         memset(d, 0, sizeof(d));
     83 
     84         p[0] = Point(0, 5);
     85         cnt = 1;
     86         for(int i = 0; i < n; ++i)
     87         {
     88             double x, y[4];
     89             scanf("%lf", &x);
     90             for(int j = 0; j < 4; ++j) { scanf("%lf", &y[j]); p[cnt++] = Point(x, y[j]); }
     91             door.push_back(Door(x, y[0], y[1], y[2], y[3]));
     92         }
     93         p[cnt++] = Point(10, 5);
     94 
     95         Init();
     96 
     97         for(int i = 0; i < cnt; ++i)
     98             for(int j = i+1; j < cnt; ++j)
     99             {
    100                 double l = Length(Vector(p[i]-p[j]));
    101                 if(p[i].x == p[j].x) continue;
    102                 if(isOK(i, j))
    103                     w[i][j] = w[j][i] = l;
    104             }
    105         //Dijkstra
    106         d[0] = 0;
    107         for(int i = 1; i < cnt; ++i) d[i] = INF;
    108         for(int i = 0; i < cnt; ++i)
    109         {
    110             int x;
    111             double m = INF;
    112             for(int y = 0; y < cnt; ++y) if(!vis[y] && d[y] <= m) m = d[x=y];
    113             vis[x] = 1;
    114             for(int y = 0; y < cnt; ++y) d[y] = min(d[y], d[x] + w[x][y]);
    115         }
    116 
    117         printf("%.2f
    ", d[cnt-1]);
    118     }
    119 
    120     return 0;
    121 }
    代码君
  • 相关阅读:
    读TIJ -6 类再生
    STM32 外设配置关键步骤-驱动出了问题,最好还是瞧瞧--待续
    oracle 10g 11g rac 虚拟环境切换
    UFLDL教程之(三)PCA and Whitening exercise
    VIM配置文件
    Codeforces 586D Phillip and Trains(DP)
    51Nod 1272最大距离 (树状数组维护前缀最小值)
    Codeforces 482B Interesting Array(线段树区间更新)
    Codechef Chef and Triangles(离散化+区间并集)
    POJ1655 Balancing Act(树的重心)
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4272796.html
Copyright © 2011-2022 走看看