UVa 248 Cutting Corners <计算几何+SPFA>
来源:互联网 发布:数据库中关系的定义 编辑:程序博客网 时间:2024/06/17 15:00
题目
题目大意:给定起点坐标和终点坐标,以及一些矩形区域的三个点坐标,求起点到终点的最短路径长度(路径不能穿过矩形矩形区域)。
分析:容易想到的是,将所有矩形的四个角以及起点和终点看做节点,若两个节点之间的连线不跨过任何矩形区域,则在此两节点间加一条边,边权即距离,如此建图后求最短路径就好了。需要注意的是,在矩形内部的节点应当删去,另外,因为我们判断是否跨过矩形是判断此线段与矩形的四条边是否规范相交,有可能此条线段是矩形的对角线,所以我们人为为每个矩形添加两条对角线,就可以解决这个问题了。
(这道题1A,开心~。。)
代码:
#include <iostream>#include <algorithm>#include <cstdio>#include <cmath>#include <bitset>#include <queue>#define V Pointusing namespace std;const double eps=1e-7;const double INF=9999.0;const int MAXN=100;struct Point;struct Point{ double x,y; Point(){} Point(double _x,double _y):x(_x),y(_y){} V operator -(Point p){ return Point(x-p.x,y-p.y); } Point operator +(V v){ return Point(x+v.x,y+v.y); }};double dis(V v){ return sqrt(v.x*v.x+v.y*v.y);}int dblcmp(double x){ return fabs(x)<eps?0:(x>0?1:-1);}double det(V v1,V v2){ return v1.x*v2.y-v1.y*v2.x;}double dot(V v1,V v2){ return v1.x*v2.x+v1.y*v2.y;}bool cross(Point a,Point b,Point c,Point d){ return (dblcmp(det(b-a,c-a))^dblcmp(det(b-a,d-a)))==-2&& (dblcmp(det(d-c,a-c))^dblcmp(det(d-c,b-c)))==-2;}bool rightAngle(Point a,Point b,Point c){ return 0==dblcmp(dot(b-a,c-a));}struct Segment{ Point p1,p2; Segment(){} Segment(Point _p1,Point _p2):p1(_p1),p2(_p2){} bool onSegment(Point& p){ return dblcmp(det(p1-p,p2-p))==0&& p.x>=min(p1.x,p2.x)&&p.x<=max(p1.x,p2.x)&& p.y>=min(p1.y,p2.y)&&p.y<=max(p1.y,p2.y); } bool intersection(Point a,Point b){ return cross(p1,p2,a,b); }};struct House{ Point p[4]; Segment s[6]; double area; House(){} House(Point *pp){ for(int i=0;i<3;++i){ if(rightAngle(pp[i],pp[(i+1)%3],pp[(i+2)%3])){ p[0]=pp[(i+1)%3]; p[1]=pp[i]; p[2]=pp[(i+2)%3]; p[3]=p[0]+(p[2]-p[1]); area=det(p[1]-p[0],p[3]-p[0]); break; } } for(int i=0;i<4;++i){ s[i]=Segment(p[i],p[(i+1)%4]); } s[4]=Segment(p[0],p[2]); s[5]=Segment(p[1],p[3]); } bool inHouse(Point pp){ bool flag=true; for(int i=0;i<4;++i){ if(s[i].onSegment(pp)){ flag=false; break; } } double areaTemp=0.0; for(int i=0;i<4;++i){ areaTemp+=fabs(det(p[i]-pp,p[(i+1)%4]-pp)); } return dblcmp(areaTemp/2.0-area)==0&&flag; }};House house[30];Point point[MAXN];int n,t;double map[MAXN][MAXN];double dist[MAXN];int p_num;Point start,endp;void buildG(){ p_num=0; point[p_num++]=start; for(int i=0;i<n;++i){ for(int j=0;j<4;++j){ int k; for(k=0;k<n;++k){ if(i==k) continue; if(house[k].inHouse(house[i].p[j])) break; } if(k==n) point[p_num++]=house[i].p[j]; } } point[p_num++]=endp; for(int i=0;i<p_num;++i){ dist[i]=INF; for(int j=i+1;j<p_num;++j){ map[i][j]=map[j][i]=INF; bool flag=true; for(int k=0;k<n&&flag;++k){ for(int v=0;v<6;++v){ if(house[k].s[v].intersection(point[i],point[j])){ flag=false; break; } } } if(flag) map[i][j]=map[j][i]=dis(point[i]-point[j]); } }}void solve(){ bitset<MAXN> vis; queue<int> q; q.push(0); dist[0]=0; vis[0]=1; while(!q.empty()){ int id=q.front(); q.pop(); vis[id]=0; for(int i=0;i<p_num;++i){ if(dist[i]>dist[id]+map[id][i]){ dist[i]=dist[id]+map[id][i]; if(!vis[i]){ vis[i]=1; q.push(i); } } } } if(t>1) putchar('\n'); printf("Scenario #%d\n route distance: %.2lf\n",t++,dist[p_num-1]);}int main(){ t=1; while(scanf("%d",&n),n!=-1){ double x1,x2,y1,y2; scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2); start=Point(x1,y1); endp=Point(x2,y2); Point pArray[3]; for(int i=0;i<n;++i){ for(int i=0;i<3;++i){ scanf("%lf %lf",&x1,&y1); pArray[i]=Point(x1,y1); } house[i]=House(pArray); } buildG(); solve(); } return 0;}
阅读全文
0 0
- UVa 248 Cutting Corners <计算几何+SPFA>
- uva 10406 - Cutting tabletops(计算几何)
- uva 10867 - Cutting a Polygon(几何)
- uva 11178 计算几何
- UVA-11178-计算几何
- UVA-11796-计算几何
- hdu 1154 poj 2462 Cutting a polygon 计算几何
- sgu198:Get Out!(计算几何+spfa判负环)
- 计算几何专项:UVa 11437
- 计算几何专项:UVa 11646
- 计算几何专项:UVa 11817
- 计算几何专项:UVa 11524
- 计算几何专项:UVa 10566
- 计算几何专项:UVa 11186
- 计算几何专项:UVa 10522
- 计算几何专项:UVa 10674
- 计算几何专项:UVa 10439
- 计算几何专项:UVa 12300
- 斯坦福大学公开课:傅里叶变换及其应用
- Android横竖屏切换个人总结
- java流
- Jmeter命令行运行实例讲解
- 建站流程篇——黑客内参教你如何快速学会做网站
- UVa 248 Cutting Corners <计算几何+SPFA>
- 获取exe所在文件的路径
- Error: ELOOP: too many symbolic links encountered
- 基于深度学习的图像语义分割技术概述之背景与深度网络架构
- 手码VGG16网络
- win7下用Intelij IDEA 远程调试spark standalone 集群
- locate命令安装
- map reduce解决数据不平衡问题
- python中什么是*args和**kwargs?