UVa 248 Cutting Corners <计算几何+SPFA>
2017-11-03 16:58
351 查看
题目
题目大意:给定起点坐标和终点坐标,以及一些矩形区域的三个点坐标,求起点到终点的最短路径长度(路径不能穿过矩形矩形区域)。
分析:容易想到的是,将所有矩形的四个角以及起点和终点看做节点,若两个节点之间的连线不跨过任何矩形区域,则在此两节点间加一条边,边权即距离,如此建图后求最短路径就好了。需要注意的是,在矩形内部的节点应当删去,另外,因为我们判断是否跨过矩形是判断此线段与矩形的四条边是否规范相交,有可能此条线段是矩形的对角线,所以我们人为为每个矩形添加两条对角线,就可以解决这个问题了。
(这道题1A,开心~。。)
代码:
题目大意:给定起点坐标和终点坐标,以及一些矩形区域的三个点坐标,求起点到终点的最短路径长度(路径不能穿过矩形矩形区域)。
分析:容易想到的是,将所有矩形的四个角以及起点和终点看做节点,若两个节点之间的连线不跨过任何矩形区域,则在此两节点间加一条边,边权即距离,如此建图后求最短路径就好了。需要注意的是,在矩形内部的节点应当删去,另外,因为我们判断是否跨过矩形是判断此线段与矩形的四条边是否规范相交,有可能此条线段是矩形的对角线,所以我们人为为每个矩形添加两条对角线,就可以解决这个问题了。
(这道题1A,开心~。。)
代码:
#include <iostream> #include <algorithm> #include <cstdio> #include <cmath> #include <bitset> #include <queue> #define V Point using 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){ 4000 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; }
相关文章推荐
- Cutting Chains UVA - 818
- flag 推进比较决策段过程用while(B<=A) Uva Rails
- uva 11424 GCD Extreme 求∑∑gcd(i,j) (1<i<n,i<j<n)
- uva 11008 Antimatter Ray Clearcutting
- uva 10733 The Colored Cubes<polya定理>
- UVA 10867 Cutting a Polygon
- Abbott的复仇(Abbott's Revenge, ACM/ICPC World Finals 2000, UVa 816)<经典BFS>
- UVA 11008 Antimatter Ray Clearcutting(记忆化搜索 + 位运算)
- uva 230 Borrowers(摘)<vector>"结构体“ 膜拜!
- UVa 818 - Cutting Chains <位运算+搜索>
- 5_6 团体队列(UVa540)<queue与STL其他容器的综合运用>
- UVA 11995 I Can Guess the Data Structure!<STL数据结构使用>
- UVA 11428 GCD - Extreme (II)(G=∑ ∑GCD(i, j)(1<=i<N,i+1<=j<=N,欧拉函数)
- UVa 10079 Pizza Cutting (water ver.)
- UVA 3902 <无根树转变成有根树> <根据深度寻找k级祖先>
- UVA_Rotation Game<旋转游戏> UVA 1343
- UVa 1572 - Self-Assembly <图论模型+拓扑排序>
- UVa 1374 - Power Calculus <IDA*算法>
- UVA 11008--Antimatter Ray Clearcutting+状态压缩记忆化搜索
- UVA 11008 Antimatter Ray Clearcutting