代码1:

#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<map>
#include<list>
#include<set>
#include<vector>
#include<queue>
#include<iomanip>
#include<math.h>
#define N 1050
#define ST 1001
#define EN 1002
#define M 10000
#define inf 1000000
#define eps 1e-8
#define ll long long
using namespace std;
inline ll Max(ll a,ll b){return a>b?a:b;}
inline ll Min(ll a,ll b){return a<b?a:b;}
struct Point{//点是2维的
double x,y;
};
struct v{
Point Start,End;
}; double Cross(Point p1,Point p2,Point p3,Point p4){//二维向量(p1p2)X(p3p4) 返回第三向量长度
double x1=p2.x-p1.x,y1=p2.y-p1.y;
double x2=p4.x-p3.x,y2=p4.y-p3.y;
return x1*y2-x2*y1; //为0表示 p1p2 与p3p4共线
//直线:不为0就是相交
}
double Cross_v(v v1,v v2){
return Cross(v1.Start,v1.End,v2.Start,v2.End);
}
double point_dis(Point p1,Point p2){
return sqrt((double)((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)));
}
bool On_Segment(Point p1,Point p2,Point p3){//p3点在 p1p2线段上
if(Cross(p1,p2,p1,p3)!=0)return false;
bool iny=(p1.y<=p3.y && p3.y<=p2.y)||(p1.y>=p3.y && p3.y>=p2.y);
bool inx=(p1.x<=p3.x && p3.x<=p2.x)||(p1.x>=p3.x && p3.x>=p2.x);
if(inx && iny)return true;
return false;
}
bool Segmentintersect(Point p1,Point p2,Point p3,Point p4){//p1p2 是否与 p3p4相交
double cross_1=Cross(p3,p4,p3,p1),cross_2=Cross(p3,p4,p3,p2);//cross_1 2必须一正一负且都不为0
double cross_3=Cross(p1,p2,p1,p3),cross_4=Cross(p1,p2,p1,p4);//cross_2 4必须一正一负且都不为0
//表示a线段 2点 在b线段 2侧
if(cross_1*cross_2<0 && cross_3*cross_4<0)return true; //a线段端点在 b线段上 视情况取舍这种位置
// if(cross_1==0 && On_Segment(p3,p4,p1))return true;
// if(cross_2==0 && On_Segment(p3,p4,p2))return true;
// if(cross_3==0 && On_Segment(p1,p2,p3))return true;
// if(cross_4==0 && On_Segment(p1,p2,p4))return true;
return false;
} //----------------------- 2维计算几何模版-------------------------------------
struct Edge{
int f,t,nex;
double w;
}edge[M];
int head[N],edgenum;
int n;
void addedge(int u,int v,double w){
Edge E={u,v,head[u],w};
edge[edgenum]=E;
head[u]=edgenum++;
} double dis[N];
void spfa(int s,int e){
queue<int>q;
bool vis[N]; memset(vis,0,sizeof(vis));
int i,u,v;
for(i=0;i<N;i++)dis[i]=inf;
dis[s]=0; vis[s]=true;
q.push(s);
while(!q.empty()){
u=q.front(); q.pop();
for(i=head[u];i!=-1;i=edge[i].nex)
{
v=edge[i].t;
if(dis[v]>dis[u]+edge[i].w){
dis[v]=dis[u]+edge[i].w;
if(!vis[v])q.push(v);
}
} }
}
Point line[N][4],Start,End;
Point Seg[N][6];
int main()
{
int i,j;
Start.x=0,Start.y=5;
End.x=10,End.y=5; while(scanf("%d",&n),n>=0)
{
for(i=0;i<n;i++){
double x,y1,y2,y3,y4;
scanf("%lf %lf%lf %lf%lf",&x,&y1,&y2,&y3,&y4);
line[i][0].x=line[i][1].x=line[i][2].x=line[i][3].x=x;
line[i][0].y=y1;
line[i][1].y=y2;
line[i][2].y=y3;
line[i][3].y=y4; Seg[i][0].x=x,Seg[i][0].y=0;
for(j=1;j<=4;j++)Seg[i][j]=line[i][j-1];
Seg[i][5].x=x,Seg[i][5].y=10; }
memset(head,-1,sizeof(head)); edgenum=0;
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++) for(int ii=0;ii<4;ii++)
for(int jj=0;jj<4;jj++)
{
bool can=true;
for(int k=i+1;k<j && can;k++)
for(int kk=0;kk<5 &&can;kk+=2)
if(Segmentintersect(line[i][ii],line[j][jj],Seg[k][kk],Seg[k][kk+1]))
can=false; if(can)addedge(i*10+ii,j*10+jj,point_dis(line[i][ii],line[j][jj]));
} for(i=0;i<n;i++)
for(int ii=0;ii<4;ii++)
{
bool cans=true,cane=true;
for(int k=0;k<i && cans;k++)
for(int kk=0;kk<5 &&cans;kk+=2)
if(Segmentintersect(Start,line[i][ii],Seg[k][kk],Seg[k][kk+1]))
cans=false; if(cans)addedge(ST,i*10+ii,point_dis(Start,line[i][ii])); for(int k=i+1;k<n && cane;k++)
for(int kk=0;kk<5 &&cane;kk+=2)
if(Segmentintersect(End,line[i][ii],Seg[k][kk],Seg[k][kk+1]))
cane=false; if(cane)addedge(i*10+ii,EN,point_dis(End,line[i][ii]));
} bool canse=true;
for(int k=0;k<n && canse;k++)
for(int kk=0;kk<5 &&canse;kk+=2)
if(Segmentintersect(Start,End,Seg[k][kk],Seg[k][kk+1]))
canse=false;
if(canse)addedge(ST,EN,point_dis(Start,End)); spfa(ST,EN);
printf("%.2lf\n",dis[EN]);
}
return 0;
}
/*
1
5 4 6 7 8
2
4 2 7 8 9
7 3 4.5 6 7 */

代码2:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<ctype.h>
#include<iomanip>
#include<set>
#include<map>
#include<list>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
const double pi=acos(-1.0);
const double eps = 1e-8;
int sgn(double x)
{
if(fabs(x) < eps)return 0;
if(x < 0)return -1;
else return 1;
}
struct Point
{
double x,y;
Point(){}
Point(double _x,double _y)
{
x = _x;y = _y;
}
Point operator -(const Point &b)const
{
return Point(x - b.x,y - b.y);
}
double operator ^(const Point &b)const
{
return x*b.y - y*b.x;
}
double operator *(const Point &b)const
{
return x*b.x + y*b.y;
}
void transXY(double B)
{
double tx = x,ty = y;
x = tx*cos(B) - ty*sin(B);
y = tx*sin(B) + ty*cos(B);
}
};
double dis(Point a,Point b)
{
double ss=a.x-b.x;
double tt=a.y-b.y;
return sqrt(ss*ss+tt*tt);
}
struct Line
{
Point s,e;
double k;
Line(){}
Line(Point _s,Point _e)
{
s = _s;e = _e;
k = atan2(e.y - s.y,e.x - s.x);
}
pair<int,Point> operator &(const Line &b)const
{
Point res = s;
if(sgn((s-e)^(b.s-b.e)) == 0)
{
if(sgn((s-b.e)^(b.s-b.e)) == 0)
return make_pair(0,res);
else return make_pair(1,res);
}
double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
res.x += (e.x-s.x)*t;
res.y += (e.y-s.y)*t;
return make_pair(2,res);
}
};
bool inter(Line l1,Line l2)
{
return
max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&
max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&
max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&
max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&
sgn((l2.s-l1.s)^(l1.e-l1.s))*sgn((l2.e-l1.s)^(l1.e-l1.s)) <= 0 &&
sgn((l1.s-l2.s)^(l2.e-l1.s))*sgn((l1.e-l2.s)^(l2.e-l2.s)) <= 0;
}
struct NODE
{
double x,y1,y2,y3,y4;
}pp[2000];
bool cmp(NODE a,NODE b)
{
return a.x<b.x;
}
#define inf 10000000
const int maxn=300010;
int head[maxn],tol,m,n;
double dist[maxn];
struct Edge
{
int to,next;
double val;
}edge[10*maxn];
void add(int u,int v,double w)
{
edge[tol].to=v;
edge[tol].next=head[u];
edge[tol].val=w;
head[u]=tol++;
}
struct Node
{
int id;
double dist;
Node(int a=0,double b=0):id(a),dist(b){}
bool operator < (const Node &b) const
{
return dist>b.dist;
}
};
void fun(int st)
{
int i,j,u,v;
priority_queue<Node> q;
q.push(Node(st,0));
for(i=1;i<=n;i++)dist[i]=inf;
dist[st]=0;
while(!q.empty())
{
Node ret=q.top();q.pop();
u=ret.id;
if(dist[u]<ret.dist)continue;
for(i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].to;
if(dist[v]>dist[u]+edge[i].val)
{
dist[v]=dist[u]+edge[i].val;
q.push(Node(v,dist[v]));
}
}
}
}
Line s1[500];
Point s2[500];
int main()
{
int i,j,k,m;
while(~scanf("%d",&m))
{
if(m==-1)break;
for(i=1;i<=m;i++)scanf("%lf%lf%lf%lf%lf",&pp[i].x,&pp[i].y1,&pp[i].y2,&pp[i].y3,&pp[i].y4);
sort(pp+1,pp+m+1,cmp);
memset(head,-1,sizeof(head));tol=0;n=0;
int indexx=0;
s2[++n]=Point(0,5);
for(i=1;i<=m;i++)
{
Point p1,p2,p3,p4,p5,p6;
p1=Point(pp[i].x,0.0);
s2[++n]=p1;
p2=Point(pp[i].x,pp[i].y1);
s2[++n]=p2;
p3=Point(pp[i].x,pp[i].y2);
s2[++n]=p3;
p4=Point(pp[i].x,pp[i].y3);
s2[++n]=p4;
p5=Point(pp[i].x,pp[i].y4);
s2[++n]=p5;
p6=Point(pp[i].x,10.0);
s2[++n]=p6;
s1[++indexx]=Line(p1,p2);
s1[++indexx]=Line(p3,p4);
s1[++indexx]=Line(p5,p6);
}
s2[++n]=Point(10,5);
for(i=1;i<=n;i++)
{
for(j=i+1;j<=n;j++)
{
if(sgn(s2[i].x-s2[j].x)==0)continue;
Line s(s2[i],s2[j]);
int flag=1;
for(k=1;k<=indexx;k++)
{
if(sgn(s1[k].s.x-s2[i].x)==0)continue;
if(sgn(s1[k].s.x-s2[j].x)==0)continue;
if(inter(s1[k],s))
{
flag=0;
break;
}
}
if(flag) add(i,j,dis(s2[i],s2[j]));
}
}
fun(1);
printf("%.2f\n",dist[n]);
}
return 0;
}

POJ 1556 计算几何+最短路的更多相关文章

  1. POJ 1556 计算几何 判断线段相交 最短路

    题意: 在一个左下角坐标为(0,0),右上角坐标为(10,10)的矩形内,起点为(0,5),终点为(10,5),中间会有许多扇垂直于x轴的门,求从起点到终点在能走的情况下的最短距离. 分析: 既然是求 ...

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

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

  3. POJ 1556 The Doors 线段交 dijkstra

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

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

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

  5. POJ 1161 Walls(最短路+枚举)

    POJ 1161 Walls(最短路+枚举) 题目背景 题目大意:题意是说有 n个小镇,他们两两之间可能存在一些墙(不是每两个都有),把整个二维平面分成多个区域,当然这些区域都是一些封闭的多边形(除了 ...

  6. ●POJ 1556 The Doors(简单计算几何+最短路)

    ●赘述题目 10*10的房间内,有竖着的一些墙(不超过18个).问从点(0,5)到(10,5)的最短路. 按照输入样例,输入的连续5个数,x,y1,y2,y3,y4,表示(x,0--y1),(x,y2 ...

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

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

  8. POJ 1556 - The Doors - [平面几何+建图spfa最短路]

    题目链接:http://poj.org/problem?id=1556 Time Limit: 1000MS Memory Limit: 10000K Description You are to f ...

  9. poj 1556 zoj1721 BellmanFord 最短路+推断直线相交

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

随机推荐

  1. Check .NET Version with Inno Setup

    原文 http://www.kynosarges.org/DotNetVersion.html Inno Setup by Jordan Russell is a great installation ...

  2. Matalab之模糊KMeans实现

    这节继续上节的KMeans进行介绍,上节主要是对模糊KMeans方法的原理做了介绍,没有实践印象总是不深刻,前段时间有个师姐让我帮着写了个模糊KMeans的算法,今天就拿她给出的例子来对这个方法做个实 ...

  3. 消息队列接口API(posix 接口和 system v接口)

    消息队列 posix API 消息队列(也叫做报文队列)能够克服早期unix通信机制的一些缺点.信号这种通信方式更像\"即时\"的通信方式,它要求接受信号的进程在某个时间范围内对信 ...

  4. 能上QQ无法打开网页

    能上QQ无法上网电脑故障解决方法 Winsock协议配置故障解决方法 第1步 :单击开始菜单中的运行,并在打开的运行窗口中键入“cmd”并回车确定,打死命令提示符窗口. 第2步 :在打开的命令提示符窗 ...

  5. #include <boost/asio.hpp>

    TCP服务端和客户端 TCP服务端 #include <iostream> #include <stdlib.h> #include <boost/asio.hpp> ...

  6. 格而知之2:UIView的autoresizingMask属性探究

    UIView的autoresizingMask属性,是用在当一个UIView实例的父控件的尺寸发生变化时,来自动调整UIView实例在父控件中的位置与尺寸的.autoresizingMask属性是一个 ...

  7. Python学习入门基础教程(learning Python)--5 Python文件处理

    本节主要讨论Python下的文件操作技术. 首先,要明白为何要学习或者说关系文件操作这件事?其实道理很简单,Python程序运行时,数据是存放在RAM里的,当Python程序运行结束后数据从RAM被清 ...

  8. TagBuilder 性能如此低下?

    本文来自:http://www.cnblogs.com/zhuisha/archive/2010/03/12/1684022.html 需要通过ASP.NET MVC生成一个列表,MVC里面根正苗红的 ...

  9. Lucene 4.4 依据Int类型字段删除索引

    1.方法一,通过Term删除 Term构造中没有.Int类型须要转换成Lucene自带的类BytesRef . /** * 依据商品ID删除索引文件 * @param id */ public voi ...

  10. PropertyGrid—为复杂属性提供下拉式编辑框和弹出式编辑框

    零.引言 PropertyGrid中我们经常看到一些下拉式的编辑方式(Color属性)和弹出式编辑框(字体),这些都是为一些复杂的属性提供的编辑方式,本文主要说明如何实现这样的编辑方式. 一.为属性提 ...