思路:二维离散化,然后算出边权,跑单源最短路径。
//#pragma GCC optimize(2) #pragma comment(linker, "/STACK:10240000,10240000") #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<string> #include<queue> #include<map> #include<set> #include<stack> #include<list> #include<ctime> #include<ctype.h> #include<stdlib.h> #include<bitset> #include<algorithm> #include<assert.h> #include<numeric> //accumulate #define endl "\n" #define fi first #define se second #define forn(i,s,t) for(int i=(s);i<=(t);++i) #define mem(a,b) memset(a,b,sizeof(a)) #define rush() int MYTESTNUM;cin>>MYTESTNUM;while(MYTESTNUM--) #define debug(x) printf("%d\n",x) #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define mp make_pair #define pb push_back #define sc(x) scanf("%d",&x) #define sc2(x,y) scanf("%d%d",&x,&y) #define sc3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define pf(x) printf("%d\n",x) #define pf2(x,y) printf("%d %d\n",x,y) #define pf3(x,y,z) printf("%d %d %d"\n,x,y,z) #define ll unsigned long long #define dd double #define pfs puts("*****") #define pfdd(x) printf("%.5f\n",(x)); using namespace std; const ll P=1e9+7; const double eps=1e-6; ll mul(ll a, ll b){ll ans = 0;for(;b;a=a*2%P,b>>=1) if(b&1) ans=(ans+a)%P;return ans;} ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;} ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;} const int maxn=406; inline int read() { int X=0,w=0; char ch=0; while(!isdigit(ch)) {w|=ch=='-';ch=getchar();} while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } int G[205][10]; int x[maxn],y[maxn]; int indx,indy,lenx,leny; int wx[maxn][maxn],wy[maxn][maxn]; int bgx,bgy,edx,edy; int vis[maxn][maxn]; dd tim[maxn][maxn]; int dir[4][2]={{1,0}, {0,1}, {0,-1}, {-1,0}}; struct node { int x, y; double t; bool operator<(const node &a) const { return a.t<t; } }; bool pd(int a,int b) { return (a>0&&a<=lenx&&b>0&&b<=leny); } inline int myabs(int a) { if(a<0) return -a; return a; } dd dijsktra(int bgx, int bgy) { priority_queue<node> q; mem(vis,0); for(int i=1;i<=lenx;++i) for(int j=1;j<=leny;++j) tim[i][j]=1e15; q.push({bgx,bgy,0}); tim[bgx][bgy]=0; while(!q.empty()) { int xx=q.top().x, yy=q.top().y; q.pop(); if(xx==edx&&yy==edy) return tim[xx][yy]; if(vis[xx][yy]) continue; vis[xx][yy]=1; for(int i=0;i<4;++i) { int sx=xx+dir[i][0], sy=yy+dir[i][1]; if(pd(sx,sy)) { dd st; if(sx==xx) st=tim[xx][yy]+(myabs(y[sy]-y[yy])*1.0)/(wy[xx][min(yy,sy)]*1.0+1.0); else st=tim[xx][yy]+(myabs(x[sx]-x[xx])*1.0)/(wx[yy][min(xx,sx)]*1.0+1.0); if(st<tim[sx][sy]) { tim[sx][sy]=st; q.push({sx,sy,tim[sx][sy]}); } } } } return -1; } int main() { rush() { int n; sc(n); indx=0,indy=0; for(int i=1;i<=n;++i) { for(int j=1;j<=4;++j) sc(G[i][j]); x[++indx]=G[i][1],x[++indx]=G[i][3],y[++indy]=G[i][2],y[++indy]=G[i][4]; } sc2(bgx,bgy); sc2(edx,edy); x[++indx]=bgx, x[++indx]=edx; y[++indy]=bgy, y[++indy]=edy; sort(x+1,x+1+indx); sort(y+1,y+1+indy); lenx=unique(x+1,x+1+indx)-x-1; leny=unique(y+1,y+1+indy)-y-1; // pf(lenx); for(int i=1;i<=n;++i) { G[i][1]=lower_bound(x+1,x+1+lenx,G[i][1])-x; G[i][2]=lower_bound(y+1,y+1+leny,G[i][2])-y; G[i][3]=lower_bound(x+1,x+1+lenx,G[i][3])-x; G[i][4]=lower_bound(y+1,y+1+leny,G[i][4])-y; } bgx=lower_bound(x+1,x+1+lenx,bgx)-x; bgy=lower_bound(y+1,y+1+leny,bgy)-y; edx=lower_bound(x+1,x+1+lenx,edx)-x; edy=lower_bound(y+1,y+1+leny,edy)-y; mem(wx,0); mem(wy,0); for(int i=1;i<=n;++i) { for(int k=G[i][2];k<=G[i][4];++k) for(int j=G[i][1]; j<G[i][3]; ++j) wx[k][j]++; for(int k=G[i][1];k<=G[i][3];++k) for(int j=G[i][2]; j<G[i][4]; ++j) wy[k][j]++; } dd ans = dijsktra(bgx,bgy); printf("%.5f\n",ans); } }