UVA_393_Doors_(计算几何基础+最短路)
2016-05-23 16:13
387 查看
描述
坐标系,x,y轴都是0~10.起点(0,5),终点(10,5),中间可能有墙,每一堵墙有两个门,给出门的上下定点的坐标,求从起点到终点的最短路.
The Doors |
You are to find the length of the shortest path through a chamber containing obstructing walls. The chamber will always have sides at x=0, x=10, y=0, and y=10. The initial and final points of the path are always (0,5) and (10,5). There will also be from 0 to 18 vertical walls inside the chamber, each with two doorways. The figure below illustrates such a chamber and also shows the path of minimal length.
#include <bits/stdc++.h> using namespace std; const int maxn=100; const double oo=~0u>>1,eps=1e-10; int wall_num,edge_num,point_num; double d[maxn][maxn]; struct Point{ double x,y; Point(double x=0,double y=0):x(x),y(y){} }p[maxn]; typedef Point Vector; Vector operator + (Vector a,Vector b){ return Vector(a.x+b.x,a.y+b.y); } Vector operator - (Vector a,Vector b){ return Vector(a.x-b.x,a.y-b.y); } Vector operator * (Vector a,double p){ return Vector(a.x*p,a.y*p); } Vector operator / (Vector a,double p){ return Vector(a.x/p,a.y/p); } struct edge{ double x1,y1,x2,y2; edge(double x1=0,double y1=0,double x2=0,double y2=0):x1(x1),y1(y1),x2(x2),y2(y2){} }g[maxn]; void add_point(double x,double y){ p[++point_num]=Point(x,y); } void add_edge(double x1,double y1,double x2,double y2){ g[++edge_num]=edge(x1,y1,x2,y2); } inline int dcmp(double x){ if(fabs(x)<eps) return 0; return x<0?-1:1; } inline double cross(Vector a,Vector b){ return a.x*b.y-a.y*b.x; } inline bool segment_cross_simple(Point a,Point b,Point c,Point d){ return (dcmp(cross(b-a,c-a))^dcmp(cross(b-a,d-a)))==-2&&(dcmp(cross(d-c,a-c))^dcmp(cross(d-c,b-c)))==-2; } inline double dis(Point a,Point b){ return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2)); } void Floyd(){ for(int k=1;k<=point_num;k++) for(int i=1;i<=point_num;i++) for(int j=1;j<=point_num;j++) d[i][j]=min(d[i][j],d[i][k]+d[k][j]); } void outit(){ for(int i=1;i<=point_num;i++){ for(int j=1;j<=point_num;j++){ printf("d[%d][%d]=%.2lf\t",i,j,d[i][j]); } printf("\n"); } } void solve(){ for(int i=1;i<=point_num;i++) for(int j=i+1;j<=point_num;j++){ bool link=true; for(int k=1;k<=edge_num;k++){ Point t1=Point(g[k].x1,g[k].y1); Point t2=Point(g[k].x2,g[k].y2); if(segment_cross_simple(p[i],p[j],t1,t2)){ link=false; break; } } if(link) d[i][j]=d[j][i]=dis(p[i],p[j]); } Floyd(); printf("%.2lf\n",d[1][2]); } int main(){ while(scanf("%d",&wall_num)&&wall_num!=-1){ point_num=edge_num=0; add_point(0,5); add_point(10,5); for(int i=1;i<=wall_num;i++){ double x,y1,y2,y3,y4; scanf("%lf%lf%lf%lf%lf",&x,&y1,&y2,&y3,&y4); add_point(x,y1); add_point(x,y2); add_point(x,y3); add_point(x,y4); add_edge(x,0,x,y1); add_edge(x,y2,x,y3); add_edge(x,y4,x,10); } for(int i=1;i<=point_num;i++){ for(int j=1;j<=point_num;j++) d[i][j]=oo; d[i][i]=0; } solve(); } return 0; }View Code
相关文章推荐
- Java常用类库初识
- linux安装nginx
- Android探索之HttpURLConnection网络请求
- Linux计划任务入门详解
- 存储
- Redis系列学习笔记14 微博功能分析
- 项目经理防雷记
- java中文乱码解决之道(6):javaWeb中的编码解码的
- Unity3d|5.3.4多场景编辑功能
- jQuery判断是否为正整数
- Mysql几种索引方式的区别及适用情况
- redis java 分页、排序示例
- warning和error的区别
- Android 应用程序发送shell命令
- UGUI研究院之开始学习搭建界面自适应屏幕
- Android图片下载机制
- sqlserver批量更新
- Redis系列学习笔记13 Lua 脚本
- GitHub Windows版本下载失败的解决方法
- tomcat(15)Digester库