zoj 1721 The Doors(最短路,构图不易)

来源:互联网 发布:近期网络热点事件 编辑:程序博客网 时间:2024/04/29 05:39

从障碍墙中求一条最短路。

题目关键就是构图==然后最短路之。

discuss里有人说此题跟写作文一般。偶当bellman的例题做的。

1.求距离

2.判阻断

3.判连通

4.bellman

判断顶点的a,b是否被某段墙阻拦,方法是如果这段墙的两个端点同时位于a,b,的一边就没被阻,不然被阻断。

一堵墙可分为三段==各种计算几何0-0

这题还是代码说清楚吧(poj没过==不知什么细致数据忽略了)

#include<stdio.h>#include<math.h>#define INF 1023123123#define MAXN 100typedef struct point{double X,Y;}point;typedef struct edge{int u,v;}edge;//---------------------------全局---------------------------int n;//墙的数目double xx[20];//每堵墙的x坐标point pp[MAXN];//门int ppnum;//点的数目double yy[20][4];//墙的y坐标double Edge[MAXN][MAXN];//邻接矩阵edge ee[MAXN*MAXN];//边int eenum;//边数//-----------------------------------------------------------double dis(point a,point b){return sqrt((a.X-b.X)*(a.X-b.X)+(a.Y-b.Y)*(a.Y-b.Y));}double cross(double x1,double y1,double x2,double y2,double x3,double y3){return (x2-x1)*(y3-y1)-(x3-x1)*(y2-y1);}bool Isok(point a,point b)//判连通{if(a.X>=b.X) return false;bool flag=true;int i=0;while(xx[i]<=a.X&&i<n)i++;int r=0,rr=0,rrr=0;while(xx[i]<b.X&&i<n){if(cross(a.X,a.Y,b.X,b.Y,xx[i],0)*cross(a.X,a.Y,b.X,b.Y,xx[i],yy[i][0])<0)r=1;if(cross(a.X,a.Y,b.X,b.Y,xx[i],yy[i][1])*cross(a.X,a.Y,b.X,b.Y,xx[i],yy[i][2])<0)rr=1;if(cross(a.X,a.Y,b.X,b.Y,xx[i],yy[i][3])*cross(a.X,a.Y,b.X,b.Y,xx[i],10)<0)rrr=1;if(r==1||rr==1||rrr==1){flag=false;break;}i++;}return flag;}double bellman(int beg,int end){double d[MAXN];int i,j;for(i=0;i<MAXN;i++){d[i]=INF;}d[beg]=0;bool ex=true;//是否可以提前退出bellman的标志。for(i=0;i<ppnum&&ex;i++){ex=false;for(j=0;j<eenum;j++)if(d[ee[j].u]<INF&&d[ee[j].v]>d[ee[j].u]+Edge[ee[j].u][ee[j].v]){d[ee[j].v]=d[ee[j].u]+Edge[ee[j].u][ee[j].v];ex=true;}}return d[end];}int main(){int i,j;while(scanf("%d",&n)){if(n==-1) break;pp[0].X=0;pp[0].Y=5;ppnum=1;for(i=0;i<n;i++){scanf("%lf",&xx[i]);for(j=0;j<4;j++){pp[ppnum].X=xx[i];scanf("%lf",&pp[ppnum].Y);yy[i][j]=pp[ppnum].Y;ppnum++;}}pp[ppnum].X=10;pp[ppnum].Y=5;ppnum++;for(i=0;i<ppnum;i++){for(j=0;j<ppnum;j++){Edge[i][j]=INF;}}eenum=0;for(i=0;i<ppnum;i++){for(j=i+1;j<ppnum;j++){if(Isok(pp[i],pp[j])){Edge[i][j]=dis(pp[i],pp[j]);ee[eenum].u=i;ee[eenum].v=j;eenum++;}}}printf("%.2lf\n",bellman(0,ppnum-1));}return 0;} 


原创粉丝点击