The Doors--poj1556(最短路+判断点与线段的关系)
http://poj.org/problem?id=1556
题目大意:从(0,5)走到(10,5)走的最短距离是多少
中间有最多18个隔着的墙 每个墙都有两个门 你只能从门通过
我的思路是 只要这两个点把能过的 就把他们的距离算出来 最后用迪杰斯塔拉算法求最短路就行了
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<ctype.h> #include<math.h> #include<algorithm> #include<iostream> using namespace std; #define N 200 const double ESP = 1e-8; #define INF 0xffffffff int vis[N]; double dis[N]; struct node { double x,y; int c; node(double x=0,double y=0,int c=0):x(x),y(y),c(c){} }p[N]; node a[N][5]; double G[N][N]; double dij(int s,int e) { memset(vis,0,sizeof(vis)); for(int i=0;i<e;i++) { dis[i]=G[s][i]; } for(int i=0;i<e;i++) { double Min=INF; int dist; for(int j=0;j<e;j++) { if(!vis[j] && Min>dis[j]) { Min=dis[j]; dist=j; } } vis[dist]=1; for(int j=0;j<e;j++) { if(!vis[j]) dis[j]=min(dis[j],dis[dist]+G[dist][j]); } } return dis[e-1]; } int main() { int n; double k[N]; while(scanf("%d",&n),n!=-1) { p[0]=node(0,5,0); int b=1; for(int i=1;i<=n;i++) { scanf("%lf",&k[i]); scanf("%lf %lf %lf %lf",&a[i][1].x,&a[i][1].y,&a[i][2].x,&a[i][2].y); p[b++]=node(k[i],a[i][1].x,i); p[b++]=node(k[i],a[i][1].y,i); p[b++]=node(k[i],a[i][2].x,i); p[b++]=node(k[i],a[i][2].y,i); } p[b++]=node(10,5,n+1); for(int i=0;i<b;i++) { for(int j=0;j<b;j++) { G[i][j]=INF; } dis[i]=INF; } for(int i=0;i<b;i++) { for(int j=i+1;j<b;j++) { if(p[i].c == p[j].c) continue; int flag=0; for(int l=p[j].c-1; l>p[i].c; l--) { double y=(k[l]-p[i].x)*(p[j].y-p[i].y)/(p[j].x-p[i].x)+p[i].y; if(a[l][1].x-y>ESP || (a[l][1].y-y<ESP && a[l][2].x-y>ESP) || (a[l][2].y-y<ESP)) { flag=1; break; } } if(flag==0) { G[i][j]=sqrt((p[j].x-p[i].x)*(p[j].x-p[i].x)+(p[j].y-p[i].y)*(p[j].y-p[i].y)); } } } double aa=dij(0,b); printf("%.2f\n",aa); } return 0; }