这个题难点在于离散的角度,一开始想的是对联通块离散,但由于联通块形态不一,所以只能dfs,效率为4e8
所以我们可以离散 直线间的间距,这样也就相当于离散了dfs的过程
所以线段的题有一个套路就是离散间距、、
注:
分清>号和>=号
码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
using namespace std;
map<int,int>mx,my;
queue<int>q;
#define N 180000
int tot,j,sx,zy,k,hou[N*4],xia[N],cnt,lx,ly,n,xx[N],yy[N],x[N],y[N],c[N],zhong[N*4],v[N*4],i,d[N],st,xxx,yyy,xxxx,yyyy;
void jia(int a,int b,int c)
{
++tot,hou[tot]=xia[a],xia[a]=tot,v[tot]=c,zhong[tot]=b;
}
int bfs(int qd)
{
q.push(qd);
for(i=1;i<=90000;i++)d[i]=99999;
d[qd]=0;
while(!q.empty())
{
st=q.front();
q.pop();
for(i=xia[st];i!=-1;i=hou[i])
{
int nd=zhong[i];
if(d[nd]<=d[st]+v[i])continue;
d[nd]=d[st]+v[i];
q.push(nd);
}
}
return d[mx[xxxx]+my[yyyy]*300];
}
int main()
{
memset(xia,-1,sizeof(xia));
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&y[i],&x[i],&c[i]);
xx[++cnt]=x[i],yy[cnt]=y[i];
xx[++cnt]=x[i]+c[i],yy[cnt]=y[i]+c[i];
}
scanf("%d%d%d%d",&yyy,&xxx,&yyyy,&xxxx);
xx[++cnt]=xxx;yy[cnt]=yyy; xx[++cnt]=xxxx;yy[cnt]=yyyy;
sort(xx+1,xx+1+cnt);
sort(yy+1,yy+1+cnt);
mx[xx[1]]=3;my[yy[1]]=3;
lx=3;ly=3;
for(i=2;i<=cnt;i++)
{
if(xx[i]!=xx[i-1])
{
if(xx[i]==xx[i-1]+1)lx++;
else lx+=2;
mx[xx[i]]=lx;
}
if(yy[i]!=yy[i-1])
{
if(yy[i]==yy[i-1]+1)ly++;
else ly+=2;
my[yy[i]]=ly;
}
}
// cout<<cnt;
for(i=1;i<=lx+2;i++)
for(j=1;j<=ly+2;j++)
{sx=zy=0;
//cout<<i<<" "<<j<<" ";
for(k=1;k<=n;k++)
{ //cout<<my[y[k]]<<" "<<my[y[k]+c[k]]<<" ";
if(my[y[k]]<=j&&my[y[k]+c[k]]>=j)
{
if(i==mx[x[k]]||i==mx[x[k]+c[k]])
{
sx=k;
}
} //cout<<mx[x[k]]<<" "<<mx[x[k]+c[k]];
if(mx[x[k]]<=i&&mx[x[k]+c[k]]>=i)
{
if(j==my[y[k]]||j==my[y[k]+c[k]])
{
zy=k;
}
}
}
if(sx==0&&zy==0)jia(i+300*j,i-1+300*j,0),jia(i+300*j,i+1+300*j,0),jia(i+300*j,i+300*(j+1),0),jia(i+300*j,i+300*(j-1),0);
if(sx&&zy)continue;
if(sx) jia(i+300*j,i-1+300*j,1),jia(i+300*j,i+1+300*j,1);
if(zy) jia(i+300*j,i+300*(j+1),1),jia(i+300*j,i+300*(j-1),1);
}
printf("%d",bfs(mx[xxx]+my[yyy]*300));
}