您的位置:首页 > 其它

POJ-1556 线段相交的判断与最短路(几何+图论)

2013-08-19 16:12 274 查看
题意:

在10*10的房间里,有些墙,问你从源点(0,5)到对面的点(10,5)的最短路,不能穿过墙。

分析:

或许看到了最短路,这题大概就有思路了,到我还是有点疑问,”为什么最短的路一定要从墙的端点过去,有没有存在一条路径从某一点(不在这些点)使它能直接到达目的地“?

而这些点是有可能的。但我听别人说过端点就行了,我也不再去追究了。

如果是过端点,那就好办了,由于点不多,枚举所以可能的路径,并判断是否有线段与它相交就行了,端点相交的不能算。

代码:

#include<cstdio>
#include<cmath>
#define INF 0x3fff
#define eps 1e-8
using namespace std;

const int M=500;
struct point{
double x,y;
}Point[M];

struct line{
point a,b;
}Line[M];

int cnt,p;
double dis[M],map[M][M];
bool vis[M];

double cross(point a,point b,point c){
return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
}

bool Judge(point a,point b,point c,point d){
return cross(a,b,c)*cross(a,b,d)<-eps;
}

bool Iscross(point a,point b)
{
for(int i=0;i<cnt;i++)
if(Judge(a,b,Line[i].a,Line[i].b)&&Judge(Line[i].a,Line[i].b,a,b)) //需要对换比较,先前只判断了一个,WA了。
return false;
return true;
}

double count(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

void set_map()
{
int i,j;
for(i=0;i<=p;i++){
for(j=i;j<=p;j++){
if(i==j) map[i][j]=0;
else map[i][j]=map[j][i]=INF;
}
}
for(i=0;i<p;i++){
for (j=i+1;j<p;j++){
if(Iscross(Point[i],Point[j])){
map[i][j]=map[j][i]=count(Point[i],Point[j]);
}
}
}
}

double dijkstra()
{
int i,j,k;
double Min;
for(i=0;i<p;i++){
dis[i]=map[0][i];
vis[i]=0;
}
dis[0]=0,vis[0]=1;
for(i=1;i<p;i++){
Min=INF;
for(j=0;j<p;j++){
if(!vis[j]&&dis[j]<Min){
Min=dis[j];
k=j;
}
}
dis[k]=Min;
vis[k]=1;
for(j=0;j<p;j++){
if(!vis[j]&&map[k][j]+dis[k]<dis[j]){
dis[j]=map[k][j]+dis[k];
}
}
}
return dis[p-1];
}

int main()
{
int n;
double x,y1,y2,y3,y4;
while(scanf("%d",&n)&&n!=-1){
cnt=p=0;
Point[p].x=0,Point[p++].y=5;
while(n--){
scanf("%lf %lf %lf %lf %lf",&x,&y1,&y2,&y3,&y4);
Line[cnt].a.x=x,Line[cnt].a.y=0; //加边
Line[cnt].b.x=x,Line[cnt++].b.y=y1;
Line[cnt].a.x=x,Line[cnt].a.y=y2;
Line[cnt].b.x=x,Line[cnt++].b.y=y3;
Line[cnt].a.x=x,Line[cnt].a.y=y4;
Line[cnt].b.x=x,Line[cnt++].b.y=10;
Point[p].x=x,Point[p++].y=y1; //加点
Point[p].x=x,Point[p++].y=y2;
Point[p].x=x,Point[p++].y=y3;
Point[p].x=x,Point[p++].y=y4;
}
Point[p].x=10,Point[p++].y=5;
set_map();
printf("%.2f\n",dijkstra()); //G++,在POJ要用%f,不能%lf。
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  几何 图论