传送门
n 2 n^2 n2暴力显然,考虑优化。
有一种想法是使用四分树/kd-tree/树套树,发现你并不能得到 100 p t s 100pts 100pts的好成绩(空间会炸掉)
考试的时候比较智熄,先暴力四分树建边然后跑dijkstra,于是动态内存炸了。。。 88 p t s 88pts 88pts滚粗。
那剩下那 12 p t s 12pts 12pts如何拿呢?
我们考虑只用四分树加入点,这样的空间开销仅有 O ( n l o g n ) O(nlog_n) O(nlogn),然后把一个点到一个矩形的边存下来,每次跑 d i j k s t r a dijkstra dijkstra的时候暴力在四分树上找被松弛的点把它们松弛之后加入堆即可。
88 p t s 88pts 88pts代码:
#include
#define ri register int
#define fi first
#define se second
#define x1 ldxx1
#define x2 ldxx2
#define y1 ldxy1
#define y2 ldxy2
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
const int N=70005,M=150005;
typedef pair<int,int> pii;
int pos[N],tot=0;
int son[M*20][4],dis[M*20];
bool in[M*20];
vector<pii>e[N];
int n,W,H,m,rt=0;
const int mogic=1e5+7;
struct Hash_table{
vector<int>ori[mogic],val[mogic];
inline int query(int x){
for(ri t=x%mogic,i=ori[t].size()-1;~i;--i)if(ori[t][i]==x)return val[t][i];
return -1;
}
inline void update(int x,int v){
int t=x%mogic;
ori[t].push_back(x),val[t].push_back(v);
}
}mp;
inline void insert(int&p,int x1,int y1,int x2,int y2,int kx,int ky,int id){
if(!p)p=++tot;
dis[p]=1e9;
if(x1==x2&&y1==y2){mp.update(p,id),pos[id]=p;return;}
int mx=x1+x2>>1,my=y1+y2>>1;
if(kx<=mx&&ky<=my)insert(son[p][0],x1,y1,mx,my,kx,ky,id);
if(kx<=mx&&ky>my)insert(son[p][1],x1,my+1,mx,y2,kx,ky,id);
if(kx>mx&&ky<=my)insert(son[p][2],mx+1,y1,x2,my,kx,ky,id);
if(kx>mx&&ky>my)insert(son[p][3],mx+1,my+1,x2,y2,kx,ky,id);
}
int ldxid,ldxw,qx1,qx2,qy1,qy2;
int cnt=0,cnt1=0;
inline bool check(int x1,int y1,int x2,int y2){return !((x2<qx1)||(x1>qx2)||(y2<qy1)||(y1>qy2));}
inline void addedge(int p,int x1,int y1,int x2,int y2){
++cnt;
if(qx1<=x1&&x2<=qx2&&qy1<=y1&&y2<=qy2){e[ldxid].push_back(pii(p,ldxw)),++cnt1;return;}
int mx=x1+x2>>1,my=y1+y2>>1;
if(son[p][0]&&check(x1,y1,mx,my))addedge(son[p][0],x1,y1,mx,my);
if(son[p][1]&&check(x1,my+1,mx,y2))addedge(son[p][1],x1,my+1,mx,y2);
if(son[p][2]&&check(mx+1,y1,x2,my))addedge(son[p][2],mx+1,y1,x2,my);
if(son[p][3]&&check(mx+1,my+1,x2,y2))addedge(son[p][3],mx+1,my+1,x2,y2);
}
inline void dijkstra(){
priority_queue<pii,vector<pii>,greater<pii> >q;
q.push(pii(dis[pos[1]]=0,pos[1]));
while(!q.empty()){
int x=q.top().se;
q.pop();
if(in[x])continue;
in[x]=1;
int p=mp.query(x);
if(p==-1){
for(ri i=0,v;i<4;++i){
if(!(v=son[x][i]))continue;
if(dis[v]>dis[x])dis[v]=dis[x],q.push(pii(dis[v],v));
}
}
else{
for(ri i=0,v,w;i<e[p].size();++i){
v=e[p][i].fi,w=e[p][i].se;
if(dis[v]>dis[x]+w)dis[v]=dis[x]+w,q.push(pii(dis[v],v));
}
}
}
for(ri i=2;i<=n;++i)cout<<dis[pos[i]]<<'\n';
}
int main(){
freopen("jump.in","r",stdin);
freopen("jump.out","w",stdout);
n=read(),m=read(),W=read(),H=read();
for(ri i=1,x,y;i<=n;++i){
x=read(),y=read();
insert(rt,1,1,W,H,x,y,i);
}
for(ri i=1,w,x1,y1,x2,y2,id;i<=m;++i){
ldxid=read(),ldxw=read(),qx1=read(),qx2=read(),qy1=read(),qy2=read();
addedge(rt,1,1,W,H);
}
dijkstra();
return 0;
}
100 p t s 100pts 100pts代码:
#include
#define ri register int
#define fi first
#define se second
#define x1 ldxx1
#define x2 ldxx2
#define y1 ldxy1
#define y2 ldxy2
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
const int N=70005,M=150005;
typedef pair<int,int> pii;
int tot=0;
int son[M*20][4],dis[M*20];
bool in[M*20];
vector<int>e[M*20];
vector<int>g[N];
int n,W,H,m,rt=0;
inline void insert(int&p,int x1,int y1,int x2,int y2,int kx,int ky,int id){
if(!p)p=++tot;
dis[p]=1e9;
if(x1==x2&&y1==y2){e[p].push_back(id);return;}
int mx=x1+x2>>1,my=y1+y2>>1;
if(kx<=mx&&ky<=my)insert(son[p][0],x1,y1,mx,my,kx,ky,id);
if(kx<=mx&&ky>my)insert(son[p][1],x1,my+1,mx,y2,kx,ky,id);
if(kx>mx&&ky<=my)insert(son[p][2],mx+1,y1,x2,my,kx,ky,id);
if(kx>mx&&ky>my)insert(son[p][3],mx+1,my+1,x2,y2,kx,ky,id);
}
int pos[M],val[M],qx1[M],qx2[M],qy1[M],qy2[M];
priority_queue<pii,vector<pii>,greater<pii> >q;
inline bool check(int x1,int y1,int x2,int y2,int id){return !((x2<qx1[id])||(x1>qx2[id])||(y2<qy1[id])||(y1>qy2[id]));}
inline void build(int p){
if(!p)return;
for(ri i=0;i<4;++i){
if(!son[p][i])continue;
e[p].push_back(son[p][i]);
build(son[p][i]);
}
}
inline void addedge(int p,int x1,int y1,int x2,int y2,int id){
if(!p||dis[p]<=dis[pos[id]]+val[id])return;
if(qx1[id]<=x1&&x2<=qx2[id]&&qy1[id]<=y1&&y2<=qy2[id]){
q.push(pii(dis[p]=dis[pos[id]]+val[id],p));
return;
}
int mx=x1+x2>>1,my=y1+y2>>1;
if(son[p][0]&&check(x1,y1,mx,my,id))addedge(son[p][0],x1,y1,mx,my,id);
if(son[p][1]&&check(x1,my+1,mx,y2,id))addedge(son[p][1],x1,my+1,mx,y2,id);
if(son[p][2]&&check(mx+1,y1,x2,my,id))addedge(son[p][2],mx+1,y1,x2,my,id);
if(son[p][3]&&check(mx+1,my+1,x2,y2,id))addedge(son[p][3],mx+1,my+1,x2,y2,id);
}
inline void dijkstra(){
q.push(pii(dis[1]=0,1));
while(!q.empty()){
int x=q.top().se;
q.pop();
if(in[x])continue;
in[x]=1;
if(x<=n)for(ri i=0;i<g[x].size();++i)addedge(rt,1,1,W,H,g[x][i]);
else{
for(ri i=0,v,w;i<e[x].size();++i){
v=e[x][i];
if(dis[v]>dis[x])q.push(pii(dis[v]=dis[x],v));
}
}
}
for(ri i=2;i<=n;++i)cout<<dis[i]<<'\n';
}
int main(){
freopen("jump.in","r",stdin);
freopen("jump.out","w",stdout);
n=read(),m=read(),W=read(),H=read();
tot=n;
for(ri i=1,x,y;i<=n;++i){
dis[i]=1e9;
x=read(),y=read();
insert(rt,1,1,W,H,x,y,i);
}
for(ri i=1,w,x1,y1,x2,y2,id;i<=m;++i){
pos[i]=read(),val[i]=read(),qx1[i]=read(),qx2[i]=read(),qy1[i]=read(),qy2[i]=read();
g[pos[i]].push_back(i);
}
build(rt);
dijkstra();
return 0;
}