luogu P1354 房间最短路问题 计算几何_Floyd_线段交
第一次写计算几何,还是很开心的吧(虽然题目好水qaq)
暴力枚举端点,暴力连边即可
用线段交判一下是否可行.
Code:
#include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #define setIO(s) freopen(s".in","r",stdin) #define maxn 100008 const double eps = 0.00000001; const double inf = 10000000000.0; using namespace std; int n,idx,ls,st,ed; double map[200][200]; struct Point{ double x,y; Point(double x=0,double y=0):x(x),y(y){} }point[maxn]; struct Line{ Point a,b; }line[maxn]; int exis(double t){ return (fabs(t)<=eps) ? 0 : (t < 0 ? -1 : 1 ) ; } double det(double x1,double y1,double x2,double y2) { return x1*y2-x2*y1; } double cross(Point a,Point b,Point c) { return det(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y); } bool check(Point a,Point b,Point c,Point d) { if((exis(cross(a,c,b)) ^ exis(cross(a,d,b)))==-2 && (exis(cross(d,a,c)) ^ exis(cross(d,b,c))) == -2) return true; return false; } double dis(Point a,Point b) { double xx = b.x - a.x; double yy = b.y - a.y; return (double)sqrt(xx*xx+yy*yy) ; } bool is_ok(int a,int b) { for(int i=1;i<=ls;++i) { if(check(line[i].a,line[i].b,point[a],point[b])) { return false; } } return true; } void addline(double a,double b,double c,double d) { line[++ls].a.x = a; line[ls].a.y = b; line[ls].b.x = c; line[ls].b.y = d; } void addedge(int u,int v,double dis) { map[u][v] = dis;} int main(){ //setIO("input"); scanf("%d",&n); for(int i=1;i<=n;++i) { double a,b,c,d,x; scanf("%lf%lf%lf%lf%lf",&x,&a,&b,&c,&d); point[++idx] = Point(x,a); point[++idx] = Point(x,b); point[++idx] = Point(x,c); point[++idx] = Point(x,d); addline(x,0,x,a); addline(x,b,x,c); addline(x,d,x,10.0); } point[++idx] = Point(0,5), st=idx; point[++idx] = Point(10,5),ed=idx; for(int i=1;i<=idx;++i) for(int j=1;j<=idx;++j) map[i][j] = inf; for(int i=1;i<=idx;++i) map[i][i]=0; for(int i=1;i<=idx;++i) for(int j=1;j<i;++j) if(i!=j&&is_ok(i,j)) addedge(i,j,dis(point[i],point[j])),addedge(j,i,dis(point[i],point[j])); for(int k=1;k<=idx;++k) for(int i=1;i<=idx;++i) for(int j=1;j<=idx;++j) if(map[i][k]+map[k][j] < map[i][j]) map[i][j] = map[i][k] + map[k][j]; printf("%.2f",map[st][ed]); return 0; }