其实是一种类似kdtree思想的分治优化建图
stO zxyoi Orz
Code:
#include<bits/stdc++.h>
#define pb push_back
#define ll long long
using namespace std;
inline int read(){
int res=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-f;ch=getchar();}
while(isdigit(ch)) {res=(res<<1)+(res<<3)+(ch^48);ch=getchar();}
return res*f;
}
const int N=7e4+5,M=2e5,INF=0x3f3f3f3f;
int n,m,w,h;
struct point{
int x,y;
int id;
}p[N];
int que[N],cnt=0;
namespace kdt{
int ls[N<<1],rs[N<<1],kd[N<<1],tot,rt;
int U[N<<1],D[N<<1],L[N<<1],R[N<<1],siz[N<<1],id[N<<1];
inline bool cmp1(const point &a,const point &b){return a.x<b.x;}
inline bool cmp2(const point &a,const point &b){return a.y<b.y;}
void build(int &rt,int l,int r,int u,int d,int ql,int qr,int last=0){
rt=++tot;
L[rt]=l,R[rt]=r,D[rt]=d,U[rt]=u;
siz[rt]=qr-ql+1;
if(ql==qr){
id[rt]=p[ql].id;
return;
}
if(u==d){
kd[u]=1;
if(last!=1) sort(p+ql,p+qr+1,cmp1);
int mid=ql+qr>>1;
build(ls[rt],l,p[mid].x,u,u,ql,mid,1);
build(rs[rt],p[mid+1].x,r,u,u,mid+1,qr,1);
return;
}
if(l==r){
kd[l]=2;
if(last!=2) sort(p+ql,p+qr+1,cmp2);
int mid=ql+qr>>1;
build(ls[rt],l,l,u,p[mid].y,ql,mid,2);
build(rs[rt],l,l,p[mid+1].y,d,mid+1,qr,2);
return;
}
kd[u]=3-last;
if(kd[u]==3) kd[u]=1;
if(kd[u]==1){
sort(p+ql,p+qr+1,cmp1);
int mid=ql+qr>>1,nu=INF,nd=0;
for(int i=ql;i<=mid;i++) nu=min(nu,p[i].y),nd=max(nd,p[i].y);
build(ls[rt],l,p[mid].x,nu,nd,ql,mid,1);
nu=INF,nd=0;
for(int i=mid+1;i<=qr;i++) nu=min(nu,p[i].y),nd=max(nd,p[i].y);
build(rs[rt],p[mid+1].x,r,nu,nd,mid+1,qr,1);
}
else{
sort(p+ql,p+qr+1,cmp2);
int mid=ql+qr>>1,nl=INF,nr=0;
for(int i=ql;i<=mid;i++) nl=min(nl,p[i].x),nr=max(nr,p[i].x);
build(ls[rt],nl,nr,u,p[mid].y,ql,mid,2);
nl=INF,nr=0;
for(int i=mid+1;i<=qr;i++) nl=min(nl,p[i].x),nr=max(nr,p[i].x);
build(rs[rt],nl,nr,p[mid+1].y,d,mid+1,qr,2);
}
}
void get(int rt,int l,int r,int u,int d){
if(!siz[rt]) return;
if(r<L[rt] || R[rt]<l || d<U[rt] || D[rt]<u) return;
if(id[rt]){
siz[rt]=0;
que[++cnt]=id[rt];
return;
}
if(kd[rt]==1){
if(l<=R[ls[rt]]) get(ls[rt],l,r,u,d);
if(L[rs[rt]]<=r) get(rs[rt],l,r,u,d);
}
else{
if(u<=D[ls[rt]]) get(ls[rt],l,r,u,d);
if(U[rs[rt]]<=d) get(rs[rt],l,r,u,d);
}
siz[rt]=siz[ls[rt]]+siz[rs[rt]];
}
}
struct mat{
int l,r,u,d;ll c;
mat(int _l,int _r,int _u,int _d,ll _c):l(_l),r(_r),u(_u),d(_d),c(_c){}
friend inline bool operator > (const mat &a,const mat &b){return a.c>b.c;}
};
vector<mat>e[N];
priority_queue< mat,vector<mat>,greater<mat> >q;
int pt[N];ll dis[N];
inline void dijkstra(){
memset(dis,0x3f,sizeof(dis));
dis[1]=0;
for(int i=0;i<e[1].size();i++) q.push(e[1][i]);
pt[1]=1;
while(!q.empty()){
int l=q.top().l,r=q.top().r,u=q.top().u,d=q.top().d;ll c=q.top().c;
q.pop();cnt=0;
kdt::get(kdt::rt,l,r,u,d);
for(int i=1;i<=cnt;i++){
int v=que[i];
if(pt[v]) continue;
pt[v]=1;
dis[v]=c;
for(int j=0;j<e[v].size();j++){
q.push(mat(e[v][j].l,e[v][j].r,e[v][j].u,e[v][j].d,e[v][j].c+c));
}
}
}
}
int mnx=INF,mxx=0,mny=INF,mxy=0;
int main(){
n=read();m=read();w=read();h=read();
for(int i=1;i<=n;i++){
p[i].x=read(),p[i].y=read(),p[i].id=i;
mnx=min(mnx,p[i].x);
mxx=max(mxx,p[i].x);
mny=min(mny,p[i].y);
mxy=max(mxy,p[i].y);
}
kdt::build(kdt::rt,mnx,mxx,mny,mxy,1,n);
for(int i=1;i<=m;++i){
int u=read(),w=read(),L=read(),R=read(),U=read(),D=read();
e[u].push_back(mat(L,R,U,D,w));
}
dijkstra();
for(int i=2;i<=n;i++) cout<<dis[i]<<"\n";
return 0;
}