您的位置:首页 > 其它

POJ 1556 计算几何 判断线段相交

2013-01-10 21:09 477 查看
题意:

房间里有n堵墙,每面墙上有两扇门,求从房间最左端中点到最右端中点的最短路径

题解:

这题就是考验耐心和仔细的。。。

纯暴力判断,单源最短路都懒得写了,直接floyd搞定。。

和平衡树写得一样长了。。

View Code

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>

#define N 1000
#define EPS 1e-8

using namespace std;

struct LINE
{
double x0,x1,y0,y1;
int bh0,bh1;
}line
;

int n,num,cnt,S,T;
double map

,dis

;

inline void read()
{
cnt=num=0;
double a,b,c,d,e;
for(int i=1;i<=n;i++)
{
scanf("%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e);
++cnt;
line[cnt].x0=a; line[cnt].y0=0; line[cnt].x1=a; line[cnt].y1=b;
line[cnt].bh0=-1; line[cnt].bh1=++num;
++cnt;
line[cnt].x0=a; line[cnt].y0=c; line[cnt].x1=a; line[cnt].y1=d;
line[cnt].bh0=++num; line[cnt].bh1=++num;
++cnt;
line[cnt].x0=a; line[cnt].y0=e; line[cnt].x1=a; line[cnt].y1=10;
line[cnt].bh0=++num; line[cnt].bh1=-1;
}
}

inline void floyd()
{
for(int k=S;k<=T;k++)
for(int i=S;i<=T;i++)
for(int j=S;j<=T;j++)
map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
}

inline double cross(double ax,double ay,double bx,double by)
{
return ax*by-ay*bx;
}

inline bool check(double ax,double ay,double bx,double by)
{
for(int i=1;i<=cnt;i++)
{
int fg1=cross(ax-bx,ay-by,line[i].x0-bx,line[i].y0-by)*cross(ax-bx,ay-by,line[i].x1-bx,line[i].y1-by);
int fg2=cross(line[i].x1-line[i].x0,line[i].y1-line[i].y0,ax-line[i].x0,ay-line[i].y0)*cross(line[i].x1-line[i].x0,line[i].y1-line[i].y0,bx-line[i].x0,by-line[i].y0);
if(fg1<-EPS&&fg2<-EPS) return false;
}
return true;
}

inline double getdis(double ax,double ay,double bx,double by)
{
return sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by));
}

inline void go()
{
S=0;T=++num;
for(int i=1;i<=cnt;i++)
{
for(int j=i;j<=cnt;j++)
{
if(line[i].bh0!=-1&&line[j].bh0!=-1) dis[line[i].bh0][line[j].bh0]=dis[line[j].bh0][line[i].bh0]=getdis(line[i].x0,line[i].y0,line[j].x0,line[j].y0);
if(line[i].bh0!=-1&&line[j].bh1!=-1) dis[line[i].bh0][line[j].bh1]=dis[line[j].bh1][line[i].bh0]=getdis(line[i].x0,line[i].y0,line[j].x1,line[j].y1);
if(line[i].bh1!=-1&&line[j].bh0!=-1) dis[line[i].bh1][line[j].bh0]=dis[line[j].bh0][line[i].bh1]=getdis(line[i].x1,line[i].y1,line[j].x0,line[j].y0);
if(line[i].bh1!=-1&&line[j].bh1!=-1) dis[line[i].bh1][line[j].bh1]=dis[line[j].bh1][line[i].bh1]=getdis(line[i].x1,line[i].y1,line[j].x1,line[j].y1);
}
if(line[i].bh0!=-1)
{
dis[line[i].bh0][S]=dis[S][line[i].bh0]=getdis(0.0,5.0,line[i].x0,line[i].y0);
dis[line[i].bh0][T]=dis[T][line[i].bh0]=getdis(10.0,5.0,line[i].x0,line[i].y0);
}
if(line[i].bh1!=-1)
{
dis[line[i].bh1][S]=dis[S][line[i].bh1]=getdis(0.0,5.0,line[i].x1,line[i].y1);
dis[line[i].bh1][T]=dis[T][line[i].bh1]=getdis(10.0,5.0,line[i].x1,line[i].y1);
}
}
dis[S][T]=dis[T][S]=10.0;

for(int i=S;i<=T;i++)
{
for(int j=S;j<=T;j++)
map[i][j]=9999999.0;
map[i][i]=0.0;
}

for(int i=1;i<=cnt;i++)
for(int j=i+1;j<=cnt;j++)
{
if(line[i].bh0!=-1&&line[j].bh0!=-1&&check(line[i].x0,line[i].y0,line[j].x0,line[j].y0))
map[line[i].bh0][line[j].bh0]=map[line[j].bh0][line[i].bh0]=dis[line[j].bh0][line[i].bh0];

if(line[i].bh0!=-1&&line[j].bh1!=-1&&check(line[i].x0,line[i].y0,line[j].x1,line[j].y1))
map[line[i].bh0][line[j].bh1]=map[line[j].bh1][line[i].bh0]=dis[line[j].bh1][line[i].bh0];

if(line[i].bh1!=-1&&line[j].bh0!=-1&&check(line[i].x1,line[i].y1,line[j].x0,line[j].y0))
map[line[i].bh1][line[j].bh0]=map[line[j].bh0][line[i].bh1]=dis[line[j].bh0][line[i].bh1];

if(line[i].bh1!=-1&&line[j].bh1!=-1&&check(line[i].x1,line[i].y1,line[j].x1,line[j].y1))
map[line[i].bh1][line[j].bh1]=map[line[j].bh1][line[i].bh1]=dis[line[j].bh1][line[i].bh1];
}
for(int i=1;i<=cnt;i++)
{
if(line[i].bh0!=-1&&check(0.0,5.0,line[i].x0,line[i].y0))
map[S][line[i].bh0]=map[line[i].bh0][S]=dis[S][line[i].bh0];
if(line[i].bh1!=-1&&check(0.0,5.0,line[i].x1,line[i].y1))
map[S][line[i].bh1]=map[line[i].bh1][S]=dis[S][line[i].bh1];
if(line[i].bh0!=-1&&check(10.0,5.0,line[i].x0,line[i].y0))
map[T][line[i].bh0]=map[line[i].bh0][T]=dis[T][line[i].bh0];
if(line[i].bh1!=-1&&check(10.0,5.0,line[i].x1,line[i].y1))
map[T][line[i].bh1]=map[line[i].bh1][T]=dis[T][line[i].bh1];
}

if(check(0.0,5.0,10.0,5.0)) map[S][T]=map[T][S]=dis[S][T];

floyd();
printf("%.2lf\n",map[S][T]);
}

int main()
{
while(scanf("%d",&n))
{
if(n==-1) break;
read(),go();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: