zoj 1721 || poj 1556 The Doors

这题就考建图的。
从0,5到10,5,建图建好了,用最短路算法就很简单了。关键判断两个点是否可以相连,因为可能这俩点中间有墙,就不能连了。判断很好想,但是写着稍微麻烦点,不过数据挺小的。
代码注释的有,直接判断连线在x下的y坐标是否在墙上,如果在墙上,就不能连。
结构体里的p数组开小了 T T 。。。WA了许久,查到这个错误费了好长时间。。。 T T。。
zoj300了^ ^
#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <algorithm> using namespace std; const int MAX = 20; const int MMAX = 80; typedef struct WALL{ double x; double p[5]; }WALL; WALL wall[MAX]; double map[MMAX][MMAX]; int n,m; double Distance(double x1,double y1,double x2,double y2) { return sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2)); } double yyy(double x1,double y1,double x2,double y2,double x) { return ( (y2-y1)/(x2-x1)*x + (x2*y1 - x1*y2)/(x2-x1) ); } bool Con(double x1,double y1,double x2,double y2,int i,int k) { int tmp; if( k < i ) return true; for(int j=i; j<=k; j++) { double y = yyy(x1,y1,x2,y2,wall[j].x); if( y >= wall[j].p[1] && y <= wall[j].p[2] || y >= wall[j].p[3] && y <= wall[j].p[4] ) continue; else return false; } return true; } void Buildmap() { double bx = 0.0,by = 5.0; double ex = 10.0,ey = 5.0; if( Con(bx,by,ex,ey,1,m) ) { double len = Distance(bx,by,ex,ey); map[0][m*4+1] = len; } for(int i=1; i<=m; i++) // 起点建图 for(int k=1; k<=4; k++) if( Con(bx,by,wall[i].x,wall[i].p[k],1,i-1) ) { double len = Distance(bx,by,wall[i].x,wall[i].p[k]); map[0][(i-1)*4+k] = len; } for(int i=1; i<=m; i++) // 终点建图 for(int k=1; k<=4; k++) if( Con(wall[i].x,wall[i].p[k],ex,ey,i+1,m) ) { double len = Distance(ex,ey,wall[i].x,wall[i].p[k]); map[(i-1)*4+k][m*4+1] = len; } for(int i=1; i<m; i++) // 中间点建图 for(int p=1; p<=4; p++) for(int k=i+1; k<=m; k++) for(int q=1; q<=4; q++) if( Con( wall[i].x,wall[i].p[p],wall[k].x,wall[k].p[q],i+1,k-1) ) { double len = Distance(wall[i].x,wall[i].p[p],wall[k].x,wall[k].p[q]); map[(i-1)*4+p][(k-1)*4+q] = len; } } const double inf = 10000000.0; double Dijkstra(int s,int t,int n) { double dis[MMAX]; fill(dis,dis+MMAX,inf); bool used[MMAX]; memset(used,false,sizeof(used)); dis[s] = 0.0; used[s] = true; int now = s; for(int i=0; i<n; i++) { for(int k=0; k<=n; k++) if( map[now][k] >= 0.0 && dis[k] > dis[now] + map[now][k] ) dis[k] = dis[now] + map[now][k]; double min = inf; for(int k=0; k<=n; k++) if( !used[k] && dis[k] < min ) min = dis[now = k]; used[now] = 1; } return dis[t]; } int main() { while( ~scanf("%d",&m) && m != -1 ) { for(int i=0; i<MMAX; i++) for(int k=0; k<MMAX; k++) map[i][k] = -1.0; for(int i=1; i<=m; i++) { scanf("%lf",&wall[i].x); for(int k=1; k<=4; k++) scanf("%lf",&wall[i].p[k]); } Buildmap(); double ans = Dijkstra(0,m*4+1,m*4+1); printf("%.2lf/n",ans); } return 0; }  

你可能感兴趣的:(zoj 1721 || poj 1556 The Doors)