房间最短路问题
https://www.luogu.org/problemnew/show/P1354
直接做,一个缺口上的两个边界分别看成两个点,这样我们就有n * 4个点
然后对于一堵墙,我们尝试将其与后面的点连边
有可能有连不上的情况,就是这条路线撞墙上了,算出一次函数的解析式判断一下即可
然后愉快跑floyd,反正这题n^3和n^2都能过
O(n ^ 3)
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<cmath> #include<iostream> using namespace std; #define O(x) cout << #x << " " << x << endl; #define B cout << "breakpoint" << endl; inline int read() { int ans = 0,op = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') op = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { (ans *= 10) += ch - '0'; ch = getchar(); } return ans * op; } typedef double db; const db inf = 99999999; const int maxn = 1005; int n; db dis[maxn][maxn]; void init() { for(int i = 1;i <= 4 * n + 4;i++) for(int j = 1;j <= 4 * n + 4;j++) dis[i][j] = inf; for(int i = 1;i <= n * 4 + 4;i++) dis[i][i] = 0; } void floyd() { for(int k = 1;k <= n * 4 + 4;k++) for(int i = 1;i <= n * 4 + 4;i++) for(int j = 1;j <= n * 4 + 4;j++) dis[i][j] = min(dis[i][j],dis[i][k] + dis[k][j]); } struct node { db x,y[5]; }a[maxn]; bool judge(int u,int v,int t1,int t2)//a的第t1个节点,b的第t2个节点 { if(v - u == 1) return 1; db x1 = a[u].x,x2 = a[v].x,y1 = a[u].y[t1],y2 = a[v].y[t2]; db k = (y2 - y1) / (x2 - x1); db b = y1 - k * x1; for(int i = u + 1;i <= v - 1;i++) { db y = k * a[i].x + b; if(y < a[i].y[1] || y > a[i].y[2] && y < a[i].y[3] || y > a[i].y[4]) return 0; } return 1; } void link_edge(int u,int v,int t1,int t2) { if(judge(u,v,t1,t2) == 0) return; db x1 = a[u].x,x2 = a[v].x,y1 = a[u].y[t1],y2 = a[v].y[t2]; db d = sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1)); dis[u * 4 + t1][v * 4 + t2] = dis[v * 4 + t2][u * 4 + t1] = d; } int main() { n = read(); for(int i = 1;i <= n;i++) scanf("%lf%lf%lf%lf%lf",&a[i].x,&a[i].y[1],&a[i].y[2],&a[i].y[3],&a[i].y[4]); a[0].x = 0,a[++n].x = 10; init(); for(int i = 1;i <= 4;i++) a[0].y[i] = a[n].y[i] = 5; for(int i = 0;i <= n;i++) for(int j = i + 1;j <= n;j++) for(int k = 1;k <= 4;k++) for(int p = 1;p <= 4;p++) link_edge(i,j,k,p); floyd(); printf("%.2lf",dis[1][n * 4 + 4]); }