POJ-1556 The Doors 线段相交+最短路
题意:在一个矩形平面内,有若干道墙,现求从左部某一点到右部某一点的最短路径。
解法:有一个事实是线路一定是从门两边的点上通过的,不可能出现从中间穿过的可能。因此我们就枚举两两点之间是否可达,这里就要使用到线段相交的判定。构好图之后就是一个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 线段相交+最短路相关推荐
- 简单几何(线段相交+最短路) POJ 1556 The Doors
题目传送门 题意:从(0, 5)走到(10, 5),中间有一些门,走的路是直线,问最短的距离 分析:关键是建图,可以保存所有的点,两点连通的条件是线段和中间的线段都不相交,建立有向图,然后用Dijks ...
- POJ 1556 The Doors(计算几何+最短路)
这题就是,处理出没两个点.假设能够到达,就连一条边,推断可不能够到达,利用线段相交去推断就可以.最后求个最短路就可以 代码: #include <cstdio> #include < ...
- Poj 1556 The Doors 计算几何+最短路
其实本题非常的无脑,无脑拍完1A,写到blog里只因为TM无脑拍也拍了很久啊= = #include <cstdio> #include <cstring> #include ...
- POJ 1556 The Doors (未完)
-- 转载于:https://www.cnblogs.com/XDJjy/p/3209296.html
- 【POJ - 1556】The Doors (计算几何,线段相交)
题干: You are to find the length of the shortest path through a chamber containing obstructing walls. ...
- poj 1556 (Dijkstra + Geometry 线段相交)
链接:http://poj.org/problem?id=1556 The Doors Time Limit: 1000MS Memory Limit: 10000K Total Submissi ...
- Segments POJ 3304 直线与线段是否相交
题目大意:给出n条线段,问是否存在一条直线,使得n条线段在直线上的投影有至少一个公共点. 题目思路:如果假设成立,那么作该直线的垂线l,该垂线l与所有线段相交,且交点可为线段中的某两个交点 证明:若有 ...
- POJ 2653 Pick-up sticks (线段相交)
题意:给你n条线段依次放到二维平面上,问最后有哪些没与前面的线段相交,即它是顶上的线段 题解:数据弱,正向纯模拟可过 但是有一个陷阱:如果我们从后面向前枚举,找与前面哪些相交,再删除前面那些相交的线段 ...
- POJ 1410 Intersection 判断线段交和点在矩形内 【计算几何】
ACM博客_kuangbin POJ 1410 Intersection(判断线段交和点在矩形内) Intersection Time Limit: 1000MS Memory Limit: 10 ...
最新文章
- 小说站 章节内容 ajax,第17章 作业分析与异步编程原理——2019年5月14日22:00
- OpenCV实现失焦模糊图像恢复
- 盘点提高国内访问 GitHub 的速度的 9 种方案
- JPA 一对一设置无效,连表查询的时候另外一个实体类的对象值为空
- XSD /xml 跟元素声明
- js 的 math 函数
- 有效的Java第三版有哪些新功能?
- kettle使用_ETL工具(kettle)-《PentahoKettle解决方案-使用PDI构建开源ETL解决方案》
- Spring Batch 使用指南
- 华为慧通值不值得去_华为 Mate 40太难抢,上半年的P40Pro还香吗?
- 例子---PHP实现网页计数器
- ssas计算度量_如何在Analysis Services(SSAS)中创建中间度量
- Atitit机器学习原理与概论book attilax总结
- h5 兑换商品 页面模版_H5商城静态页面(模板)
- 一次失败的Thoughtworks面试经历
- Kik CEO Ted Livingston发博称要成为西方的微信?
- ArduPilot之开源代码LibrarySketches设计
- 一文带你掌握MYSQL数据库
- OC-Xml文件解析
- vue中this.$confirm,确定和取消执行不同的逻辑处理