您的位置:首页 > 其它

UVA_393_Doors_(计算几何基础+最短路)

2016-05-23 16:13 323 查看

描述

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=5&page=show_problem&problem=329

坐标系,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

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: