The Doors
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 7641   Accepted: 2987

Description

You are to find the length of the shortest path through a chamber containing obstructing walls. The chamber will always have sides at x = 0, x = 10, y = 0, and y = 10. The initial and final points of the path are always (0, 5) and (10, 5). There will also be from 0 to 18 vertical walls inside the chamber, each with two doorways. The figure below illustrates such a chamber and also shows the path of minimal length.

Input

The input data for the illustrated chamber would appear as follows.

2

4 2 7 8 9

7 3 4.5 6 7

The first line contains the number of interior walls. Then there is a
line for each such wall, containing five real numbers. The first number
is the x coordinate of the wall (0 < x < 10), and the remaining
four are the y coordinates of the ends of the doorways in that wall. The
x coordinates of the walls are in increasing order, and within each
line the y coordinates are in increasing order. The input file will
contain at least one such set of data. The end of the data comes when
the number of walls is -1.

Output

The
output should contain one line of output for each chamber. The line
should contain the minimal path length rounded to two decimal places
past the decimal point, and always showing the two decimal places past
the decimal point. The line should contain no blanks.

Sample Input

1
5 4 6 7 8
2
4 2 7 8 9
7 3 4.5 6 7
-1

Sample Output

10.00
10.06 不错的一个题.
题意:求(0,5)和(10,5)两个点之间的最短距离
先把每个点和每条线段记录下来,然后每两个点之间如果能够直连就根据下标记录下来距离(这里要判断两个点连成的线段是否与其之间的所有线段有交点,有交点就不能直连,我用了两个变量对自身线段做了特判)然后用最短路算法进行求解。三层循环0MS,这题数据也是水。
#include <iostream>
#include <cstdio>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std; struct Point{
double x,y;
}p[];
struct Line{
Point a,b;
}line[];
int n;
const double INF = ;
double mp[][];
double low[];
bool vis[];
double dijstra(int n){
memset(vis,false,sizeof(vis));
memset(low,,sizeof(low));
int pos = ;
vis[pos]=true;
for(int i=;i<=n;i++){
low[i] = mp[pos][i];
}
for(int i=;i<n-;i++){
int mi = INF;
for(int j=;j<=n;j++){
if(!vis[j]&&mi>low[j]){
pos = j;
mi = low[j];
}
}
vis[pos] = true;
for(int j=;j<=n;j++){
if(!vis[j]&&mp[pos][j]+low[pos]<low[j]){
low[j] = mp[pos][j]+low[pos];
}
}
}
return low[n];
}
double dis(Point a,Point b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
} ///叉积
double mult(Point a, Point b, Point c)
{
return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
} ///a, b为一条线段两端点c, d为另一条线段的两端点 相交返回true, 不相交返回false
bool isCross(Point a, Point b, Point c, Point d)
{
if (max(a.x,b.x)<min(c.x,d.x))return false;
if (max(a.y,b.y)<min(c.y,d.y))return false;
if (max(c.x,d.x)<min(a.x,b.x))return false;
if (max(c.y,d.y)<min(a.y,b.y))return false;
if (mult(c, b, a)*mult(b, d, a)<)return false;
if (mult(a, d, c)*mult(d, b, c)<)return false;
return true;
}
void addline(double x,double y1,double y2,int &k){
line[k].a.x = line[k].b.x =x;
line[k].a.y = y1;
line[k].b.y = y2;
k++;
} int main()
{
while(scanf("%d",&n)!=EOF&&n!=-){
int k = ,m=; ///k代表线段的条数,m代表点的个数
p[].x = ,p[].y = ; ///起点
for(int i=;i<n;i++){
double x,y1,y2,y3,y4;
scanf("%lf%lf%lf%lf%lf",&x,&y1,&y2,&y3,&y4);
p[m].x =x,p[m++].y = y1;
p[m].x =x,p[m++].y = y2;
p[m].x =x,p[m++].y = y3;
p[m].x =x,p[m++].y = y4;
addline(x,,y1,k);
addline(x,y2,y3,k);
addline(x,y4,,k);
}
p[m].x = ,p[m].y = ; ///终点
for(int i=;i<=m;i++){
for(int j=;j<=m;j++) mp[i][j]=INF;
}
for(int i=;i<=m;i++){
for(int j=i+;j<=m;j++){
Line l;
l.a.x = p[i].x,l.a.y = p[i].y;
l.b.x = p[j].x,l.b.y = p[j].y;
if(l.a.x==l.b.x) continue;
int temp,temp1;
for(int t=;t<k;t++){ ///特判
if(line[t].a.x==p[j].x&&line[t].a.y==p[j].y) {
temp = t;break;
}
if(line[t].b.x==p[j].x&&line[t].b.y==p[j].y) {
temp = t;break;
}
}
for(int t=;t<k;t++){
if(line[t].a.x==p[i].x&&line[t].a.y==p[i].y) {
temp1 = t;break;
}
if(line[t].b.x==p[i].x&&line[t].b.y==p[i].y) {
temp1 = t;break;
}
}
bool flag = true;
for(int t=;t<k;t++){
if(t==temp||t==temp1) continue;
if(isCross(l.a,l.b,line[t].a,line[t].b)){
flag = false;
break;
}
}
if(flag){
mp[i][j] = mp[j][i] = dis(p[i],p[j]);
}
}
}
double ans = dijstra(m);
printf("%.2lf\n",ans);
}
return ;
}

poj 1556(迪杰斯特拉+计算几何)的更多相关文章

  1. POJ 2502 Subway(迪杰斯特拉)

    Subway Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6692   Accepted: 2177 Descriptio ...

  2. POJ 1062 昂贵的聘礼 (最短路 迪杰斯特拉 )

    题目链接 Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请 ...

  3. Poj 3268 Silver cow party 迪杰斯特拉+反向矩阵

    Silver cow party 迪杰斯特拉+反向 题意 有n个农场,编号1到n,每个农场都有一头牛.他们想要举行一个party,其他牛到要一个定好的农场中去.每个农场之间有路相连,但是这个路是单向的 ...

  4. C#迪杰斯特拉算法

    C#迪杰斯特拉算法 网上有许多版本的,自己还是写一个理解点 Dijkstra.cs public class Dijkstra { private List<Node> _nodes; p ...

  5. C++迪杰斯特拉算法求最短路径

    一:算法历史 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以 ...

  6. 【算法杂谈】LJX的迪杰斯特拉算法报告

    迪杰斯特拉(di jie qi)算法 这里有一张图: 假设要求从1号节点到5号节点的最短路.那么根据迪杰斯特拉算法的思想,我们先看: 节点1,从节点1出发的一共有3条路,分别是1-6.1-3.1-2. ...

  7. C# 迪杰斯特拉算法 Dijkstra

    什么也不想说,现在直接上封装的方法: using System; using System.Collections.Concurrent; using System.Collections.Gener ...

  8. 迪杰斯特拉(dijkstra)算法的简要理解和c语言实现(源码)

    迪杰斯特拉(dijkstra)算法:求最短路径的算法,数据结构课程中学习的内容. 1 . 理解 算法思想::设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合 ...

  9. 图-最短路径-Dijktra(迪杰斯特拉)算法

    1. 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉算法于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以起始 ...

随机推荐

  1. 【iOS开发】iOS开发CGRectGetMidX. CGRectGetMidY.CGRectGetMinY. CGRectGetMaxY. CGRectGetMinX. CGRectGetMaxX的使用

    UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 110, 150)]; label.backgroundColor ...

  2. python的三种控制流

    什么是控制流 >>控制代码执行顺序的语句 >>python中有哪些控制流 >>顺序结构 >>> a = 7 >>> print( ...

  3. thinkphp3.2 验证码的使用

    验证码生成: public function verify(){ ob_clean(); $verify = new \Think\Verify; $verify->codeSet = '012 ...

  4. 用户代理UA

    简介: 用户代理英文全称为User Agent,简称UA,现在被广泛用来标识浏览器客户端信息. 发展状况: User Agent在互联网早期就已经存在,那时互联网是完全基于文本的,用户直接浏览器互联网 ...

  5. Dubbo 的 Helloworld

    前提条件 安装好了 ZooKeeper 作为注册中心 服务端 <?xml version="1.0" encoding="UTF-8"?> < ...

  6. Hibernate常用方法之_插入

    1.使用session的save方法进行插入 public void saveUser(User user){ Session session = null; Transaction transact ...

  7. Netscaler GSLB的主备数据中心解决方案

    Netscaler GSLB的主备数据中心解决方案 http://blog.51cto.com/caojin/1898182 GSLB的主.备数据中心解决方案思路: 其实这只是多数据中心的一个特例而已 ...

  8. C&C++——基本说明

    预处理器(Preprocessor) 1 . 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define SECONDS_PER_YEAR (60 * 60 * ...

  9. 运用yunwei.zip压缩包安装过程:

    12   yum install lrzsz -y     13  rz    14  ll    15  unzip -o yunwei.zip     16  unzip yunwei.zip  ...

  10. 图片和base64编码字符串 互相转换,图片和byte数组互相转换

    图片和base64编码字符串 互相转换 import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import java.io.*; ...