【POJ 1556】The Doors 判断线段相交+SPFA
黑书上的一道例题:如果走最短路则会碰到点,除非中间没有障碍。
这样把能一步走到的点两两连边,然后跑SPFA即可。
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100003
using namespace std;
struct Point {
double x, y;
Point(double _x = 0, double _y = 0) : x(_x), y(_y) {}
};
inline int dcmp(double a) {
return (fabs(a) < 1e-6) ? 0 : (a < 0 ? -1 : 1);
}
Point operator - (Point a, Point b) {
return Point(a.x - b.x, a.y - b.y);
}
bool operator == (Point a, Point b) {
return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}
inline double Cross(Point a, Point b) {
return a.x * b.y - a.y * b.x;
}
inline double Dot(Point a, Point b) {
return a.x * b.x + a.y * b.y;
}
inline bool jiao(Point d1, Point d2, Point d3, Point d4) {
return (dcmp(Cross(d4 - d3, d1 - d3)) ^ dcmp(Cross(d4 - d3, d2 - d3))) == -2 &&
(dcmp(Cross(d2 - d1, d3 - d1)) ^ dcmp(Cross(d2 - d1, d4 - d1))) == -2;
}
inline int bjiao(Point d1, Point d2, Point d3) {
if (d1 == d2 || d1 == d3)
return 1;
if (dcmp(Cross(d2 - d1, d3 - d1)) == 0 && dcmp(Dot(d2 - d1, d3 - d1)) == -1)
return 1;
return 0;
}
inline double dis(Point d1, Point d2) {
return sqrt((d2.y - d1.y) * (d2.y - d1.y) + (d2.x - d1.x) * (d2.x - d1.x));
} struct nodeline {
Point a, b;
nodeline(Point _a = (0, 0) , Point _b = (0, 0)) : a(_a), b(_b) {}
} line[N]; struct node {
int nxt, to;
double w;
} E[N << 1]; Point a[N];
int n, cnt, lcnt, point[N], dd, q[N];
double nowx, nowy, nowy2, dist[N];
bool vis[N]; inline void ins(int x, int y, double z) {++dd; E[dd].nxt = point[x]; E[dd].to = y; E[dd].w = z; point[x] = dd;}
inline double spfa(int S, int T) {
memset(dist, 127, sizeof(dist));
memset(vis, 0, sizeof(vis));
int head = 0, tail = 1;
q[1] = S;
vis[S] = 1;
dist[S] = 0;
while (head != tail) {
++head; if (head >= N) head %= N;
int u = q[head];
vis[u] = 0;
for(int tmp = point[u]; tmp; tmp = E[tmp].nxt) {
int v = E[tmp].to;
if (dist[u] + E[tmp].w < dist[v]) {
dist[v] = dist[u] + E[tmp].w;
if (!vis[v]) {
++tail; if (tail >= N) tail %= N;
q[tail] = v;
vis[v] = 1;
}
}
}
}
return dist[T];
} inline bool check(Point d1, Point d2) {
for(int i = 1; i <= lcnt; ++i)
if (jiao(d1, d2, line[i].a, line[i].b))
return 0;
return 1;
} int main() {
scanf("%d", &n);
while (n != -1) {
cnt = 2;
lcnt = 0;
a[1].x = 0;
a[1].y = 5;
a[2].x = 10;
a[2].y = 5;
for(int i = 1; i <= n; ++i) {
scanf("%lf", &nowx);
scanf("%lf", &nowy);
a[++cnt] = Point(nowx, nowy);
line[++lcnt] = nodeline(Point(nowx, 0), a[cnt]);
scanf("%lf", &nowy);
a[++cnt] = Point(nowx, nowy);
scanf("%lf", &nowy2);
a[++cnt] = Point(nowx, nowy2);
line[++lcnt] = nodeline(a[cnt - 1], a[cnt]);
scanf("%lf", &nowy);
a[++cnt] = Point(nowx, nowy);
line[++lcnt] = nodeline(a[cnt], Point(nowx, 10));
} memset(point, 0 , sizeof(point));
dd = 0;
for(int i = 1; i <= cnt; ++i)
for(int j = i + 1; j <= cnt; ++j)
if (check(a[i], a[j]))
ins(i, j, dis(a[i], a[j]));
for(int i = 1; i <= cnt; ++i)
if (i != 2 && check(a[i], a[2]))
ins(i, 2, dis(a[i], a[2]));
printf("%.2lf\n", spfa(1,2));
scanf("%d", &n);
}
return 0;
}
清明节机房也放假啊滚来滚去……~(~o ̄▽ ̄)~o 。。。滚来滚去……o~(_△_o~) ~。。。
【POJ 1556】The Doors 判断线段相交+SPFA的更多相关文章
- poj 1556 The Doors(线段相交,最短路)
The Doors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7430 Accepted: 2915 Descr ...
- POJ 1556 The Doors(线段相交+最短路)
题目: Description You are to find the length of the shortest path through a chamber containing obstruc ...
- POJ 1556 The Doors(线段交+最短路)
The Doors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5210 Accepted: 2124 Descrip ...
- POJ 1556 - The Doors - [平面几何+建图spfa最短路]
题目链接:http://poj.org/problem?id=1556 Time Limit: 1000MS Memory Limit: 10000K Description You are to f ...
- poj 1556 (Dijkstra + Geometry 线段相交)
链接:http://poj.org/problem?id=1556 The Doors Time Limit: 1000MS Memory Limit: 10000K Total Submissi ...
- POJ 2653 Pick-up sticks (判断线段相交)
Pick-up sticks Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 10330 Accepted: 3833 D ...
- POJ 1556 - The Doors 线段相交不含端点
POJ 1556 - The Doors题意: 在 10x10 的空间里有很多垂直的墙,不能穿墙,问你从(0,5) 到 (10,5)的最短距离是多少. 分析: 要么直达,要么 ...
- POJ 1556 The Doors【最短路+线段相交】
思路:暴力判断每个点连成的线段是否被墙挡住,构建图.求最短路. 思路很简单,但是实现比较复杂,模版一定要可靠. #include<stdio.h> #include<string.h ...
- 简单几何(线段相交+最短路) POJ 1556 The Doors
题目传送门 题意:从(0, 5)走到(10, 5),中间有一些门,走的路是直线,问最短的距离 分析:关键是建图,可以保存所有的点,两点连通的条件是线段和中间的线段都不相交,建立有向图,然后用Dijks ...
随机推荐
- MIT 6.824 : Spring 2015 lab2 训练笔记
源代码参见我的github:https://github.com/YaoZengzeng/MIT-6.824 Lab 2:Primary/Backup Key/Value Service Overvi ...
- Gprinter热敏打印机光栅位图点阵数据解析工具
最近参与的项目有一个需求,解析佳博热敏打印机的光栅位图点阵数据并保存为图片文件.数据是通过Bus Hound抓取的,如下图所示. 其中1b 40为初始化打印机的指令,对应的ASCII码为ESC @,1 ...
- AngularJS Filters
过滤器可以使用一个管道字符(|)添加到表达式和指令中. AngularJS 过滤器 AngularJS 过滤器可用于转换数据: 过滤器 描述 currency 格式化数字为货币格式. filter 从 ...
- 洛谷⑨月月赛Round2 P3393逃离僵尸岛[最短路]
题目描述 小a住的国家被僵尸侵略了!小a打算逃离到该国唯一的国际空港逃出这个国家. 该国有N个城市,城市之间有道路相连.一共有M条双向道路.保证没有自环和重边. K个城市已经被僵尸控制了,如果贸然闯入 ...
- AC日记——将字符串中的小写字母换成大写字母 openjudge 1.7 13
13:将字符串中的小写字母转换成大写字母 总时间限制: 1000ms 内存限制: 65536kB 描述 给定一个字符串,将其中所有的小写字母转换成大写字母. 输入 输入一行,包含一个字符串(长度不 ...
- 终于可以在centos下使用QQ啦!
电脑装了centos 6.4操作系统,一直无法使用QQ,在centos中文论坛看到一篇介绍安装qq的文章,依样画葫芦,终于成功了1.下载QQ2012软件安装包,我给大家准备好了下载地址 [root@b ...
- Linux字符设备驱动解析
1.驱动即是一个内核模块,需要模块初始化函数 module_init() module_exit() 2.分配cdev struct cdev dev; 3.初始化cdev并定义file_operat ...
- java 25 - 1 网络编程的概述
网络编程概述 计算机网络 是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统. ...
- python黑客编程之端口爆破
#coding:utf-8 from optparse import OptionParser import time,re,sys,threading,Queue import ftplib,soc ...
- noip模拟赛(一)宠物之战
宠物之战 (senso.pas/c/cpp) [问题描述] 众所周知,moreD的宠物已经被moreD奴役得体无完肤.这只宠物实在忍无可忍,把自己每天走魔法树的经历告诉了自己的宠物.同时他还说明了自己 ...