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

来源:互联网 发布:天书世界 血盾数据 编辑:程序博客网 时间:2024/05/20 00:17

题意:

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

分析:

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

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

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

代码:

#include<cstdio>#include<cmath>#define INF 0x3fff#define eps 1e-8using 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;}