您的位置:首页 > 其它

poj 1556 The Doors(线段相交,最短路)

2016-02-03 21:27 405 查看
The Doors

Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 7430Accepted: 2915
Description

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<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std;

const int N = 300+10;
const double INF = 1e9;
const double eps = 1e-8;

int dcmp(double x) {
if(x<eps) return 0; else return x<0? -1:1;
}

struct Pt {
double x,y;
Pt(double x=0,double y=0):x(x),y(y) {};
};
struct Seg { Pt a1,a2; };
typedef Pt vec;

vec operator - (Pt A,Pt B) { return vec(A.x-B.x,A.y-B.y); }
bool operator != (Pt A,Pt B) {
if(dcmp(A.x-B.x)==0 && dcmp(A.y-B.y)==0) return 0;
else return 1;
}

double cross(Pt A,Pt B) { return A.x*B.y-A.y*B.x; }

bool SegInter(Pt s1, Pt e1, Pt s2, Pt e2) {
if(
cross(e1-s1,s2-s1) * cross(e1-s1,e2-s1) <= 0 &&
cross(e2-s2,s1-s2) * cross(e2-s2,e1-s2) <= 0
) return true;
return false;
}
double dist(Pt a,Pt b) {
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double f

;
Seg L
; int lc;
Pt P
; int pc;
int n;

int main() {
while(scanf("%d",&n)==1 && n>0) {
pc=lc=0;
FOR(i,1,n) {
double x,y1,y2,y3,y4;
scanf("%lf%lf%lf%lf%lf",&x,&y1,&y2,&y3,&y4);
L[++lc]=(Seg) {Pt(x,0),Pt(x,y1)};
L[++lc]=(Seg) {Pt(x,y2),Pt(x,y3)};
L[++lc]=(Seg) {Pt(x,y4),Pt(x,10)};
P[++pc]=Pt(x,y1) , P[++pc]=Pt(x,y2);
P[++pc]=Pt(x,y3) , P[++pc]=Pt(x,y4);
}
P[++pc]=Pt(0,5), P[++pc]=Pt(10,5);
FOR(i,1,pc) FOR(j,1,pc) f[i][j]=INF;
FOR(i,1,pc) FOR(j,i+1,pc) {
bool flag=1;
FOR(k,1,lc)
if(SegInter(P[i],P[j],L[k].a1,L[k].a2))
{ flag=0; break; }
if(flag)
f[i][j]=f[j][i]=dist(P[i],P[j]);
}
FOR(i,1,n) {
FOR(j,i+1,n) if(f[i][j]!=INF)
printf("%d,%d : %.2lf\n",i,j,f[i][j]);
}
FOR(k,1,pc) FOR(i,1,pc) FOR(j,1,pc)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
printf("%.2lf\n",f[pc-1][pc]);
}
return 0;
}


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