题意:在一个矩形平面内,有若干道墙,现求从左部某一点到右部某一点的最短路径。

解法:有一个事实是线路一定是从门两边的点上通过的,不可能出现从中间穿过的可能。因此我们就枚举两两点之间是否可达,这里就要使用到线段相交的判定。构好图之后就是一个spfa搞定。

代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;int N;struct Wall {double x, a, b, c, d;
}w[20];struct Point {double x, y;
}e[105];
int idx;struct Line {Point a, b;Line(Point x, Point y) {a = x, b = y;}friend bool cross(const Line &, const Line &);
};double G[105][105];bool cross(const Line & Line1, const Line & Line2) {double Xa1 = Line1.a.x;double Ya1 = Line1.a.y;double Xa2 = Line1.b.x;double Ya2 = Line1.b.y;double Xb1 = Line2.a.x;double Yb1 = Line2.a.y;double Xb2 = Line2.b.x;double Yb2 = Line2.b.y;if(((Xa2-Xa1)*(Yb1-Ya1)-(Xb1-Xa1)*(Ya2-Ya1))*((Xa2-Xa1)*(Yb2-Ya1)-(Xb2-Xa1)*(Ya2-Ya1))>0)return false;if(((Xb2-Xb1)*(Ya1-Yb1)-(Xa1-Xb1)*(Yb2-Yb1))*((Xb2-Xb1)*(Ya2-Yb1)-(Xa2-Xb1)*(Yb2-Yb1))>0)return false;return true;
}void insert(double x, double y) {e[idx].x = x, e[idx].y = y;++idx;
}bool legal(int x, int y) {Line line = Line(e[x], e[y]);int l = (x-1)/4, r = (y-1)/4; // 分别计算出这些点属于哪一面墙,再枚举中间的墙if (x == 0) l = -1;    // x==0时需特殊处理for (int i = l+1; i < r; ++i) { // 计算是否被墙挡住if (!cross(line, Line(e[i*4+1], e[i*4+2])) // 如果不从中间墙的某道门穿过的话 && !cross(line, Line(e[i*4+3], e[i*4+4]))) {return false;}}return true;
}double dist(const Point & a, const Point & b) {return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}void build() {for (int i = 0; i < idx; ++i) {for (int j = i + 1; j < idx; ++j) { // 枚举所有的两两组合 if (legal(i, j)) {G[i][j] = dist(e[i], e[j]);}}}
}#include <queue>
bool vis[105];
double dis[105];
void spfa() {memset(vis, 0, sizeof (vis));for (int i = 0; i < idx; ++i) {dis[i] = 10000000;    }dis[0] = 0;queue<int>q;q.push(0);vis[0] = true;while (!q.empty()) {int v = q.front();q.pop();        vis[v] = false;for (int i = v+1; i < idx; ++i) {if (G[v][i] != 10000000 && dis[i] > dis[v] + G[v][i]) {dis[i] = dis[v] + G[v][i];if (!vis[i]) {vis[i] = true;    q.push(i);}}}    }
}int main() {while (scanf("%d", &N), N != -1) {for (int i = 0; i < 105; ++i) {for (int j = 0; j < 105; ++j) {G[i][j] = 10000000;    }}idx = 0;insert(0.0, 5.0);for (int i = 0; i < N; ++i) {scanf("%lf %lf %lf %lf %lf", &w[i].x, &w[i].a, &w[i].b, &w[i].c, &w[i].d);insert(w[i].x, w[i].a), insert(w[i].x, w[i].b);insert(w[i].x, w[i].c), insert(w[i].x, w[i].d);// 读取所有的墙,并且添加四个点
        }insert(10, 5);build();spfa();printf("%.2f\n", dis[idx-1]);}return 0;
}

POJ-1556 The Doors 线段相交+最短路相关推荐

  1. 简单几何(线段相交+最短路) POJ 1556 The Doors

    题目传送门 题意:从(0, 5)走到(10, 5),中间有一些门,走的路是直线,问最短的距离 分析:关键是建图,可以保存所有的点,两点连通的条件是线段和中间的线段都不相交,建立有向图,然后用Dijks ...

  2. POJ 1556 The Doors(计算几何+最短路)

    这题就是,处理出没两个点.假设能够到达,就连一条边,推断可不能够到达,利用线段相交去推断就可以.最后求个最短路就可以 代码: #include <cstdio> #include < ...

  3. Poj 1556 The Doors 计算几何+最短路

    其实本题非常的无脑,无脑拍完1A,写到blog里只因为TM无脑拍也拍了很久啊= = #include <cstdio> #include <cstring> #include ...

  4. POJ 1556 The Doors (未完)

    -- 转载于:https://www.cnblogs.com/XDJjy/p/3209296.html

  5. 【POJ - 1556】The Doors (计算几何,线段相交)

    题干: You are to find the length of the shortest path through a chamber containing obstructing walls. ...

  6. poj 1556 (Dijkstra + Geometry 线段相交)

    链接:http://poj.org/problem?id=1556 The Doors Time Limit: 1000MS   Memory Limit: 10000K Total Submissi ...

  7. Segments POJ 3304 直线与线段是否相交

    题目大意:给出n条线段,问是否存在一条直线,使得n条线段在直线上的投影有至少一个公共点. 题目思路:如果假设成立,那么作该直线的垂线l,该垂线l与所有线段相交,且交点可为线段中的某两个交点 证明:若有 ...

  8. POJ 2653 Pick-up sticks (线段相交)

    题意:给你n条线段依次放到二维平面上,问最后有哪些没与前面的线段相交,即它是顶上的线段 题解:数据弱,正向纯模拟可过 但是有一个陷阱:如果我们从后面向前枚举,找与前面哪些相交,再删除前面那些相交的线段 ...

  9. POJ 1410 Intersection 判断线段交和点在矩形内 【计算几何】

    ACM博客_kuangbin POJ 1410 Intersection(判断线段交和点在矩形内) Intersection Time Limit: 1000MS   Memory Limit: 10 ...

最新文章

  1. 小说站 章节内容 ajax,第17章 作业分析与异步编程原理——2019年5月14日22:00
  2. OpenCV实现失焦模糊图像恢复
  3. 盘点提高国内访问 GitHub 的速度的 9 种方案
  4. JPA 一对一设置无效,连表查询的时候另外一个实体类的对象值为空
  5. XSD /xml 跟元素声明
  6. js 的 math 函数
  7. 有效的Java第三版有哪些新功能?
  8. kettle使用_ETL工具(kettle)-《PentahoKettle解决方案-使用PDI构建开源ETL解决方案》
  9. Spring Batch 使用指南
  10. 华为慧通值不值得去_华为 Mate 40太难抢,上半年的P40Pro还香吗?
  11. 例子---PHP实现网页计数器
  12. ssas计算度量_如何在Analysis Services(SSAS)中创建中间度量
  13. Atitit机器学习原理与概论book attilax总结
  14. h5 兑换商品 页面模版_H5商城静态页面(模板)
  15. 一次失败的Thoughtworks面试经历
  16. Kik CEO Ted Livingston发博称要成为西方的微信?
  17. ArduPilot之开源代码LibrarySketches设计
  18. 一文带你掌握MYSQL数据库
  19. OC-Xml文件解析
  20. vue中this.$confirm,确定和取消执行不同的逻辑处理

热门文章

  1. 2018-2019-2 《Java程序设计》第6周学习总结
  2. CSRFGuard工具介绍
  3. django配置templates、static、media和连接mysql数据库
  4. 索引( index )
  5. 各种排序笔记---基于比较排序部分
  6. 网站出现403 Forbidden
  7. 求二叉树中节点的最大距离
  8. 修复IE9-- safari 的sort方法
  9. 笔记:less的三种使用方法
  10. 在树莓派是安装并配置NTP服务