POJ 1556 The Doors
计算几何+最短路
枚举线段是否相交建图,然后跑最短路
#include<cstdio> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<algorithm> using namespace std; const int maxn=1000+10; const double eps=1e-8; int n; int totP,totL; struct point { double x; double y; } p[1000]; struct Line { point a; point b; } line[1000]; struct Path { int to; double val; Path(int t,double v) { to=t; val=v; } }; vector<Path>G[maxn]; queue<int>Q; bool flag[maxn]; double d[maxn]; double xmult(point p1,point p2,point p0) { return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); } int opposite_side(point p1,point p2,point l1,point l2) { return xmult(l1,p1,l2)*xmult(l1,p2,l2)<-eps; } int intersect_ex(point u1,point u2,point v1,point v2) { return opposite_side(u1,u2,v1,v2)&&opposite_side(v1,v2,u1,u2); } void read() { totP=0,totL=0; p[totP].x=0,p[totP++].y=5; for(int i=1; i<=n; i++) { double x,a,b,c,d; scanf("%lf%lf%lf%lf%lf",&x,&a,&b,&c,&d); p[totP+0].x=x,p[totP+0].y=0; p[totP+1].x=x,p[totP+1].y=a; p[totP+2].x=x,p[totP+2].y=b; p[totP+3].x=x,p[totP+3].y=c; p[totP+4].x=x,p[totP+4].y=d; p[totP+5].x=x,p[totP+5].y=10; line[totL].a=p[totP+0]; line[totL].b=p[totP+1]; totL++; line[totL].a=p[totP+2]; line[totL].b=p[totP+3]; totL++; line[totL].a=p[totP+4]; line[totL].b=p[totP+5]; totL++; totP=totP+6; } p[totP].x=10,p[totP++].y=5; } double dis(point a,point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } void SPFA() { memset(flag,0,sizeof flag); for(int i=0; i<=1000; i++) d[i]=9999999; while(!Q.empty()) Q.pop(); Q.push(0); flag[0]=1; d[0]=0; while(!Q.empty()) { int head=Q.front(); Q.pop(); for(int i=0; i<G[head].size(); i++) { Path path=G[head][i]; if(d[head]+path.val<d[path.to]) { d[path.to]=d[head]+path.val; if(!flag[path.to]) { flag[path.to]=1; Q.push(path.to); } } } } } int main() { while(~scanf("%d",&n)) { if(n==-1) break; read(); for(int i=0; i<=1000; i++) G[i].clear(); for(int i=0; i<totP; i++) { for(int j=i+1; j<totP; j++) { if(abs(p[i].x-p[j].x)<eps) continue; bool fail=0; for(int k=0; k<totL; k++) if(intersect_ex(p[i],p[j],line[k].a,line[k].b)) fail=1; if(!fail) { double len=dis(p[i],p[j]); Path path(j,len); G[i].push_back(path); } } } SPFA(); printf("%.2f\n",d[totP-1]); } return 0; }