题面:BZOJ1967 Luogu2537
考虑到坐标范围非常大,但是矩阵数目很少
所以考虑离散化(离散化这个过程真的恶心)
离散化的时候要注意把矩形的边左右或者上下都给留下来,这样才能给机器人跑路
离散化之后呢跑一遍spfa,注意边界处理
就是说不能连续在一条边界上面走
至于两个矩形的边交叉处不必担心,因为往交叉处走的话必定不是最优的
最后输出终点的最短路径即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<ctime>
#include<climits>
#include<string>
using namespace std;
const int dx[5]={0,1,-1,0,0};
const int dy[5]={0,0,0,1,-1};
struct ppap{int x,y;};
queue<ppap>q;
int sx,sy,zx,zy;
int n,x[1001],y[1001],c[1001],nn,mm;
int aa[1000005]={0},bb[1000005]={0};
int disx[10001],disy[10001],dist[301][301];
bool vis[301][301];int b[301][301];
int ans=0;
inline int read(){
int k=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){k=k*10+ch-'0';ch=getchar();}
return k*f;
}
inline int spfa(int sx,int sy){
for(int i=1;i<=nn;i++)
for(int j=1;j<=mm;j++)dist[i][j]=1e9;
memset(vis,0,sizeof vis);
dist[sx][sy]=0;ppap rp;rp.x=sx;rp.y=sy;q.push(rp);
while(!q.empty()){
ppap now=q.front();q.pop();
int xx=now.x,yy=now.y;
for(int i=1;i<=4;i++){
int p,nx=xx+dx[i],ny=yy+dy[i];
if(!b[nx][ny])p=0;
else if(b[nx][ny]==b[xx][yy])continue;
else p=1;
if(dist[nx][ny]>dist[xx][yy]+p){
dist[nx][ny]=dist[xx][yy]+p;
if(!vis[nx][ny]){
ppap pr;pr.x=nx;pr.y=ny;q.push(pr);
vis[nx][ny]=1;
}
}
}
vis[xx][yy]=0;
}
}
int main()
{
n=read();
for(int i=1;i<=n;i++){
x[i]=read();y[i]=read();c[i]=read();
aa[x[i]+1]=aa[x[i]]=aa[x[i]-1]=1;
bb[y[i]]=bb[y[i]-1]=bb[y[i]+1]=1;
aa[x[i]+c[i]+1]=aa[x[i]+c[i]]=aa[x[i]+c[i]-1]=1;
bb[y[i]+c[i]+1]=bb[y[i]+c[i]]=bb[y[i]+c[i]-1]=1;
}
sx=read();sy=read();zx=read();zy=read();
aa[sx]=aa[zx]=1;bb[sy]=bb[zy]=1;
int p=0,q=0;
for(int i=0;i<=1000001;i++)if(aa[i]){
q++;aa[i]=q;if(q>1)disx[q]=i-p;
p=i;
}
nn=q;p=q=0;
for(int i=0;i<=1000001;i++)if(bb[i]){
q++;bb[i]=q;if(q>1)disy[q]=i-p;
p=i;
}
mm=q;
sx=aa[sx];sy=bb[sy];zx=aa[zx];zy=bb[zy];
for(int i=1;i<=n;i++){
int xx=x[i],dx=x[i]+c[i],xy=y[i],dy=y[i]+c[i];
xx=aa[xx];xy=bb[xy];dx=aa[dx];dy=bb[dy];
for(int j=xx;j<=dx;j++)b[j][xy]=b[j][dy]=i;
for(int j=xy;j<=dy;j++)b[xx][j]=b[dx][j]=i;
}//离散化
spfa(sx,sy);
printf("%d",dist[zx][zy]);
return 0;
}