Uva393 The Doors.

来源:互联网 发布:petshop7.0源码下载 编辑:程序博客网 时间:2024/06/04 18:24

原题链接:点击打开链接

题目大意:在一个(10*10)平面内,求出发点(0,5)到终点(10,5) 的最短距离。


计算几何的基本题目,利用叉积来判断线段门与门之间是否能够相连,然后用dijkstra求最短路经

#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>#include <cmath>#include <iomanip>using namespace std;const double maxdist=0x7FFFFFFF;int wall_num;int edge_num;int point_num;double precision=0.00000001;//用来控制判断精度double dist[100];double point_dist[100][100];struct edge_node{  double x1,x2,y1,y2;}edge[80];struct point_node{  double x,y;}point[100];/* *在边的集合里添加边 *在点的集合里添加点 */void add_edge(double x1,double y1,double x2,double y2){  edge[edge_num].x1=x1;  edge[edge_num].x2=x2;  edge[edge_num].y1=y1;  edge[edge_num].y2=y2;  ++edge_num;}void add_point(double x,double y){  point[point_num].x=x;  point[point_num].y=y;  point_num++;}/* *使用dijkstra求两点之间 */void dijkstra(){  for (int i=1;i<point_num;i++)    dist[i]=maxdist;  bool reach[100];  memset(reach,true,sizeof(reach));  for (int i=1;i<=point_num;i++){    int pos;    double value=maxdist;    for (int j=0;j<point_num;j++)      if (dist[j]<value && reach[j]){value=dist[j];pos=j;      }    reach[pos]=false;    for (int j=0;j<point_num;j++)      if (reach[j] &&   dist[pos]+point_dist[pos][j]<dist[j]){dist[j]=dist[pos]+point_dist[pos][j];      }  }}/* *以下一连串子程序用叉积来判断两条线段是否相交 */double det(double x1,double y1,double x2,double y2){  return x1*y2-x2*y1;}double cross(point_node a,point_node b,point_node c){  return det(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);}int cmp(double d){  if (fabs(d)<precision)    return 0;  return (d>0)?1:-1;}bool segment_cross_simple(point_node a,point_node b,point_node c,point_node d){  if (((cmp(cross(a,c,d))^cmp(cross(b,c,d)))==-2)&&      ((cmp(cross(c,a,b))^cmp(cross(d,a,b)))==-2))    return true;  else    return false;}/* *解决过程 */void solve(){  /*   *初始化过程   */  memset(edge,0,sizeof(edge));  memset(point,0,sizeof(point));  memset(dist,0,sizeof(dist));  memset(point_dist,0,sizeof(point_dist));  //点集和边集清零  edge_num=0;  point_num=0;  add_point(0,5);  add_point(10,5);  //增加起点和终点  for (int i=1;i<=wall_num;i++){    double x,y1,y2,y3,y4;    cin >> x >> y1 >> y2 >> y3 >> y4;        //输入每个墙,并添加墙所对应的边    add_edge(x,0,x,y1);    add_edge(x,y2,x,y3);    add_edge(x,y4,x,10);    //添加墙所对应的新增顶点    add_point(x,y1);    add_point(x,y2);    add_point(x,y3);    add_point(x,y4);  }    for (int i=0;i<point_num;i++)    for (int j=0;j<point_num;j++)//枚举任意两个点      if (i!=j){//如果他们不是同一个点bool link=true;for (int k=0;k<edge_num;k++){  point_node lv,lv2;  lv.x=edge[k].x1;lv.y=edge[k].y1;  lv2.x=edge[k].x2;lv2.y=edge[k].y2;  if (segment_cross_simple(point[i],point[j],lv,lv2))    link=false;}if (link)  point_dist[i][j]=sqrt(pow(point[i].x-point[j].x,2)+pow(point[i].y-point[j].y,2));else  point_dist[i][j]=maxdist;      }  //对于任意两个顶点求他们之间的路径  dijkstra();  //求出源点开始的dijkstra  cout << setiosflags(ios::fixed)        << setprecision(2)        << dist[1] << endl; }/* *主过程 */int main(){  cin >> wall_num;  while (wall_num!=-1){    solve();    cin >> wall_num;  }}


原创粉丝点击