http://poj.org/problem?id=1556

The Doors
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 6120   Accepted: 2455

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. 





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

Source


開始的时候真的是二逼了,

1、推断相交的函数写错了,我竟然推断的是是不是跟源点和终点的直线相交。。。二逼啊,,,

2、然后改了之后还wa,由于推断里少了个!,,,,没取反,,,

3、极限的点,比方每道墙的最上沿和最下沿,这两个点不可达,就是说从源头到终点不能经过这两个点,開始的时候没排除,尽管那样的话也能AC,还是题目数据太弱了啊

我自己写的推断直线相交的模板:

/*==========================================================*\
|| 推断点在直线上或直线相交
1、函数值为0,表示在直线上;
2、test(a,b,t1)*test(a,b,t2)<0表示直线ab和直线t1t2相交
\*==========================================================*/
double test(Point a,Point b, Point t)
{
return (b.y-a.y)*(t.x-b.x)-(b.x-a.x)*(t.y-b.y);
}

思路还是比較顺的,就是最短路+推断直线相交

贴代码:

#include<cstdio>
#include<cstring>
#include <string>
#include <map>
#include <iostream>
#include <cmath>
using namespace std;
#define INF 10000
const double eps=1e-6; const int MAXN = 1011;
#define Max(a,b) (a)>(b)?(a):(b)
int cntp;
int wn;
struct Point{
Point(double x=0,double y=0):x(x),y(y){}
double x,y;
int id;
}p[MAXN];
struct Wall{
double s1,e1;
double s2,e2;
double s3;
}w[20];//=0~~=wn
double e[MAXN][MAXN],dist[MAXN]; double dis(Point a, Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
} void init()
{
cntp=1;
for(int i=0;i<=MAXN;i++)
for(int j=0;j<=MAXN;j++)
{
if(i == j)e[i][j]=0;
else e[i][j]=INF;
}
p[0].x=0,p[0].y=5,p[0].id=0;
for(int i=0;i<=MAXN;i++)dist[i]=INF;
} double test(Point a,Point b, Point t)
{
return (b.y-a.y)*(t.x-b.x)-(b.x-a.x)*(t.y-b.y);
} bool Judge(Point a, Point b)
{
if(a.id>b.id)
{
Point t=a;
a=b;
b=t;
}
//int flag=1;
if(a.id>0)
if(a.y -0.0 <=eps||10.0-a.y <=eps)
return 0;
if(b.id<cntp-1)
if(b.y-0.0<=eps || 10.0-b.y<=eps)
return 0; for(int i=a.id+1;i<b.id;i++)
{
Point p1(w[i].s1,w[i].e1),p2(w[i].s1,w[i].s2),p3(w[i].s1,w[i].e2),p4(w[i].s1,w[i].s3); if(!(
test(a,b,p1)*test(a,b,p2)<0 ||
test(a,b,p3)*test(a,b,p4)<0)
)return 0;
}
/*for(int i=a.id+1;i<b.id;i++)
{
if(!(
(w[i].e1<5.0&&w[i].s2>5.0)
|| (w[i].e2<5.0&&w[i].s3>5.0)
)
)return 0;
}*/
return 1;
} void Build()
{
for(int i=0;i<cntp;i++)
{
for(int j=i+1;j<cntp;j++)
{
//if(i == j)continue;
if(p[i].id == p[j].id)continue; if(Judge(p[i],p[j]))
{
e[i][j]=min(e[i][j],dis(p[i],p[j]));
}
}
}
} void Bellman(int v0)
{
int n=cntp;
for(int i=0;i<cntp;i++)
{
dist[i]=e[v0][i];
//if(i!=v0 && dist[i]<INF)
}
for(int k=2;k<n;k++)
{
for(int u=0;u<n;u++)
{
if(u!=v0)
{
for(int j=0;j<n;j++)
{
if(e[j][u]!=INF && dist[j]+e[j][u]<dist[u])
{
dist[u]=dist[j]+e[j][u];
}
}
}
}
}
} int main()
{
// freopen("poj1556.txt","r",stdin);
while(~scanf("%d",&wn) && ~wn)
{
init();
for(int i=1;i<=wn;i++)
{
scanf("%lf%lf%lf%lf%lf",&w[i].s1,&w[i].e1,&w[i].s2,&w[i].e2,&w[i].s3);
p[cntp].id=p[cntp+1].id=p[cntp+2].id=p[cntp+3].id=p[cntp+4].id=p[cntp+5].id=i;
p[cntp].x=p[cntp+1].x=p[cntp+2].x=p[cntp+3].x=p[cntp+4].x=p[cntp+5].x=w[i].s1;
p[cntp].y=0.0,p[cntp+1].y=w[i].e1,p[cntp+2].y=w[i].s2,p[cntp+3].y=w[i].e2,p[cntp+4].y=w[i].s3,p[cntp+5].y=10.0;
////////////////
//e[cntp+1][cntp+2]=w[i].s2-w[i].e1;
// e[cntp+3][cntp+4]=w[i].s3-w[i].e2;
cntp+=6;
}
p[cntp].x=10.0,p[cntp].y=5.0,p[cntp].id=++wn;
cntp++;
//if()
Build();
Bellman(0);
printf("%.2lf\n",dist[cntp-1]);
///////////////////
// for(int i=0;i<cntp;i++)
// printf("%d %lf\n",i,dist[i]);
}
return 0;
}

poj 1556 zoj1721 BellmanFord 最短路+推断直线相交的更多相关文章

  1. POJ 1039 Pipe【经典线段与直线相交】

    链接: http://poj.org/problem?id=1039 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...

  2. [ACM] POJ 3259 Wormholes (bellman-ford最短路径,推断是否存在负权回路)

    Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 29971   Accepted: 10844 Descr ...

  3. 最短路+线段交 POJ 1556 好题

    // 最短路+线段交 POJ 1556 好题 // 题意:从(0,5)到(10,5)的最短距离,中间有n堵墙,每堵上有两扇门可以通过 // 思路:先存图.直接n^2来暴力,不好写.分成三部分,起点 终 ...

  4. POJ 1556 - The Doors 线段相交不含端点

    POJ 1556 - The Doors题意:    在 10x10 的空间里有很多垂直的墙,不能穿墙,问你从(0,5) 到 (10,5)的最短距离是多少.    分析:        要么直达,要么 ...

  5. POJ 1556 The Doors 线段交 dijkstra

    LINK 题意:在$10*10$的几何平面内,给出n条垂直x轴的线,且在线上开了两个口,起点为$(0, 5)$,终点为$(10, 5)$,问起点到终点不与其他线段相交的情况下的最小距离. 思路:将每个 ...

  6. 直线相交 POJ 1269

    // 直线相交 POJ 1269 // #include <bits/stdc++.h> #include <iostream> #include <cstdio> ...

  7. 判断线段和直线相交 POJ 3304

    // 判断线段和直线相交 POJ 3304 // 思路: // 如果存在一条直线和所有线段相交,那么平移该直线一定可以经过线段上任意两个点,并且和所有线段相交. #include <cstdio ...

  8. POJ 3635 - Full Tank? - [最短路变形][手写二叉堆优化Dijkstra][配对堆优化Dijkstra]

    题目链接:http://poj.org/problem?id=3635 题意题解等均参考:POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]. 一些口胡: ...

  9. POJ 1269 Intersecing Lines (直线相交)

    题目: Description We all know that a pair of distinct points on a plane defines a line and that a pair ...

随机推荐

  1. 程序猿常识--OJ系统和ACM测试考试大全

    OJ它是Online Judge缩写系统,来在线检測程序源码的正确性. 著名的OJ有RQNOJ.URAL等. 国内著名的题库有北京大学题库.浙江大学题库等. 国外的题库包含乌拉尔大学.瓦拉杜利德大学题 ...

  2. yarn环境跑mapreduce报错某个container 600s未报告进度超时被杀

    问题: 发现每次reduce阶段跑到98%,相关的container被杀.报出的log大概的意思:container 600s未报告进度超时被杀 解决的方法: 在mapreduce程序里加上 conf ...

  3. windows 设置脚本IP

    毫无疑问,在windows设置IP非常方便,因为有操作简单,直观的界面.通过图形用户界面设置IP在一般情况下是足够.但是,对于那些谁经常出差,由人产生的转换工作,这样的变化IP无疑耗时且不方便.假设一 ...

  4. [Linux]history 显示命令的运行时间

    显示线时间历史命令 这里的环境是centos5.8 vim ~/.bashrc 或者 ~/.bash_profile 添加 export HISTTIMEFORMAT="%F %T &quo ...

  5. C和指针 (pointers on C)——第十章:结构和联合(下一个)锻炼

    //1.本章只为了刷存在演习.. . typedef struct phone { char * quhao; char * jiaohuantai; char * zhanhaoma; }; typ ...

  6. 必须掌握的八个cmd命令

    原文:必须掌握的八个cmd命令 一.ping 它是用来检查网络是否通畅或者网络连接速度的命令.作为一个生活在网络上的管理员或者黑客来说,ping命令是第一个必须掌握的DOS命令,它所利用的原理是这样的 ...

  7. ocp认证考试指南第一章

    数据库存储结构: 物理数据库存储结构: 必须的三类文件: 控制文件(controlFile):multiplexing the controfile 多路复用控制文件,指向其它关键文件,存储序列号和时 ...

  8. EXCEL 两人的建立Y轴

    在本文中,EXCEL2013基于,操作的其他版本基本上相同模式 原始数据和最后的结果如下面的: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvanloX2p ...

  9. Linux经常使用的命令(必看)

    http://www.importnew.com/12425.html     http://www.importnew.com/13107.html http://www.importnew.com ...

  10. Ubuntu 当黑屏解决方案安装

    前几天我就已经安装Red hat 企业版,只是可惜它并没有提供数据源.我能够安装自己的软件,但我不能完全靠解决,因此,我们决定改变系统,最后我选择ubuntu.随时下载系统.然后用u盘制作启动盘,全部 ...