POJ 1556 计算几何+最短路
代码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 计算几何+最短路的更多相关文章
- POJ 1556 计算几何 判断线段相交 最短路
题意: 在一个左下角坐标为(0,0),右上角坐标为(10,10)的矩形内,起点为(0,5),终点为(10,5),中间会有许多扇垂直于x轴的门,求从起点到终点在能走的情况下的最短距离. 分析: 既然是求 ...
- 最短路+线段交 POJ 1556 好题
// 最短路+线段交 POJ 1556 好题 // 题意:从(0,5)到(10,5)的最短距离,中间有n堵墙,每堵上有两扇门可以通过 // 思路:先存图.直接n^2来暴力,不好写.分成三部分,起点 终 ...
- POJ 1556 The Doors 线段交 dijkstra
LINK 题意:在$10*10$的几何平面内,给出n条垂直x轴的线,且在线上开了两个口,起点为$(0, 5)$,终点为$(10, 5)$,问起点到终点不与其他线段相交的情况下的最小距离. 思路:将每个 ...
- POJ 1556 - The Doors 线段相交不含端点
POJ 1556 - The Doors题意: 在 10x10 的空间里有很多垂直的墙,不能穿墙,问你从(0,5) 到 (10,5)的最短距离是多少. 分析: 要么直达,要么 ...
- POJ 1161 Walls(最短路+枚举)
POJ 1161 Walls(最短路+枚举) 题目背景 题目大意:题意是说有 n个小镇,他们两两之间可能存在一些墙(不是每两个都有),把整个二维平面分成多个区域,当然这些区域都是一些封闭的多边形(除了 ...
- ●POJ 1556 The Doors(简单计算几何+最短路)
●赘述题目 10*10的房间内,有竖着的一些墙(不超过18个).问从点(0,5)到(10,5)的最短路. 按照输入样例,输入的连续5个数,x,y1,y2,y3,y4,表示(x,0--y1),(x,y2 ...
- POJ 1556 The Doors(计算几何+最短路)
这题就是,处理出没两个点.假设能够到达,就连一条边,推断可不能够到达,利用线段相交去推断就可以.最后求个最短路就可以 代码: #include <cstdio> #include < ...
- POJ 1556 - The Doors - [平面几何+建图spfa最短路]
题目链接:http://poj.org/problem?id=1556 Time Limit: 1000MS Memory Limit: 10000K Description You are to f ...
- poj 1556 zoj1721 BellmanFord 最短路+推断直线相交
http://poj.org/problem?id=1556 The Doors Time Limit: 1000MS Memory Limit: 10000K Total Submissions ...
随机推荐
- Virtualbox下实现Ubuntu虚拟机和win7主机文件共享(很简单,亲自试用,按此步骤一般都会成功)
最近做一个操作系统实验,第一个实验即是实现Ubantu虚拟机与主机之间的共享. 本例用的是VirtualBox虚拟机,若使用Vmware WorkStation虚拟机则方法与下文介绍略有不同,但基本相 ...
- http协言和web本质
http协议和web本质 作为一个开发者,尤其是web开发人员,我想你有必要去了解这一系列的处理流程,在这期间,浏览器和服务器到底是如何打交道的?服务器又是如何处理的?浏览器又是如何将网页显示给用户的 ...
- Poj 1269 Intersecting Lines_几何模板
#include <iostream> #include <math.h> #include <iomanip> #define eps 1e-8 #define ...
- python-django如何在sae中使用自带ImageField和FileField -django-上善若水小站
python-django如何在sae中使用自带ImageField和FileField -django-上善若水小站 python-django如何在sae中使用自带ImageField和FileF ...
- hdu 5623 KK's Number(dp)
问题描述 我们可爱的KK有一个有趣的数学游戏:这个游戏需要两个人,有N\left(1\leq N\leq 5*{10}^{4} \right)N(1≤N≤5∗104)个数,每次KK都会先拿数.每 ...
- jquery如何获得页面元素的坐标值
http://www.cnblogs.com/pansly/archive/2011/05/25/2056222.html jquery如何获得页面元素的坐标值 yulutxt是输入经典语录的输入 ...
- BZOJ 1833 ZJOI2010 count 数字计数 数位DP
题目大意:求[a,b]间全部的整数中0~9每一个数字出现了几次 令f[i]为i位数(算前导零)中每一个数出现的次数(一定是同样的,所以仅仅记录一个即可了) 有f[i]=f[i-1]*10+10^(i- ...
- 有用的HTML+CSS片段
HTML5页面模板 现在国外很多制作新网站直接使用了HTML5代码,当然我们也得跟上,下面是一个常用的HTML5默认模板,就像你用Dreamweaver新建一个HTML文件时的代码,只不过现在这个是H ...
- EF项目中应用出现问题???
最近用EF做了个项目发现很多不便利的地方. 具体如下. 1,我是通过edmx 建模,然后通过模型生成数据库. 虽然数据库已经创建成功但是问题来了,我在加字段,和标的时候再次生成时domeo.edmx. ...
- JS功能代码集锦
只作 说明 逻辑用 1.模仿fade in(),fade out(). 原理:setInterval ( "opacity++透明度“函数,时间间隔) var alpha = 0; func ...