Mindis 2019百度之星初赛第一轮

由于矩形边界是算的,所以我们离散化的时候需要加点,用来表示相邻两个左边之间的区间,1是x=1,3是x=2,2就是numx[x=2]-numx[x=1],点是没有长度的,区间是有长度的。

我们用差分来统计离散化后每个点被多少矩形所覆盖了,就能知道这个地方的速度,那么这里如果是个区间,那么时间就是区间长度/速度,否则时间就是0

然后建图,跑dijkstra。

#include
#define maxl 1010
using namespace std;

const long long inf=1ll<<62;
const double eps=1e-8;

int n,m,cas,cnt,cntx,cnty,totx,toty,numcnt;
int xa,ya,xb,yb;
struct rec
{
	int x1,x2,y1,y2;
}a[maxl];
int ehead[maxl*maxl];
struct ed
{
	int to,nxt;
	double l;
}e[maxl*maxl*8];
int numx[maxl],numy[maxl];
int num[maxl][maxl];
int sum[maxl][maxl];
double ans;
double dis[maxl*maxl];
char s[maxl];
int tx[5]={0,1,0,-1,0};
int ty[5]={0,0,-1,0,1};
typedef pair p;
priority_queue,greater

>q; bool in[maxl*maxl]; inline void add(int u,int v,double l) { e[++cnt].to=v;e[cnt].l=l; e[cnt].nxt=ehead[u];ehead[u]=cnt; } inline void prework() { cntx=0;cnty=0; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2); numx[++cntx]=a[i].x1;numx[++cntx]=a[i].x2; numy[++cnty]=a[i].y1;numy[++cnty]=a[i].y2; } scanf("%d%d%d%d",&xa,&ya,&xb,&yb); numx[++cntx]=xa;numx[++cntx]=xb; numy[++cnty]=ya;numy[++cnty]=yb; sort(numx+1,numx+1+cntx); totx=unique(numx+1,numx+1+cntx)-numx-1; sort(numy+1,numy+1+cnty); toty=unique(numy+1,numy+1+cnty)-numy-1; numcnt=0; for(int i=1;i<=2*totx;i++) for(int j=1;j<=2*toty;j++) { sum[i][j]=0; num[i][j]=++numcnt; dis[numcnt]=inf; ehead[numcnt]=0; in[numcnt]=false; } int id; for(int i=1;i<=n;i++) { id=lower_bound(numx+1,numx+1+totx,a[i].x1)-numx; a[i].x1=id*2-1; id=lower_bound(numx+1,numx+1+totx,a[i].x2)-numx; a[i].x2=id*2-1; id=lower_bound(numy+1,numy+1+toty,a[i].y1)-numy; a[i].y1=id*2-1; id=lower_bound(numy+1,numy+1+toty,a[i].y2)-numy; a[i].y2=id*2-1; for(int j=a[i].x1;j<=a[i].x2;j++) { sum[j][a[i].y1]++; sum[j][a[i].y2+1]--; } } id=lower_bound(numx+1,numx+1+totx,xa)-numx; xa=id*2-1; id=lower_bound(numx+1,numx+1+totx,xb)-numx; xb=id*2-1; id=lower_bound(numy+1,numy+1+toty,ya)-numy; ya=id*2-1; id=lower_bound(numy+1,numy+1+toty,yb)-numy; yb=id*2-1; for(int i=1;i<=2*totx;i++) for(int j=1;j<=2*toty;j++) sum[i][j]=sum[i][j]+sum[i][j-1]; int x,y; double len,v; cnt=0; for(int i=1;i<=2*totx;i+=2) for(int j=1;j<=2*toty;j+=2) for(int k=1;k<=4;k++) { x=i+tx[k]*2;y=j+ty[k]*2; if(x<0 || x>2*totx || y<0 || y>2*toty) continue; if(xi) len=numx[(x+1)/2]-numx[x/2]; if(y>j) len=numy[(y+1)/2]-numy[y/2]; if(ydis[u]+e[i].l+eps) { dis[v]=dis[u]+e[i].l; q.push(make_pair(dis[v],v)); } } } return dis[en]; } inline void mainwork() { if(xa==xb && ya==yb) { ans=0; return; } ans=dij(num[xa][ya],num[xb][yb]); } inline void print() { printf("%.5f\n",ans); } int main() { int t=1; scanf("%d",&t); for(cas=1;cas<=t;cas++) { prework(); mainwork(); print(); } return 0; }

 

你可能感兴趣的:(最短路)