loj 3159 [NOI2019]弹跳
loj 3159 [NOI2019]弹跳
Tutorial
https://www.cnblogs.com/PinkRabbit/p/NOI2019D2T1.html
这是一道最短路,其中每条边从一个点连向一个矩形内的点.
对于这一类的题,我们在dijkstra的优先队列中不在储存点,而是储存边,具体来说就是更新一个点的距离时,将它的所有边加入优先队列;每次从优先队列中取出一条边,更新其所到矩形内的所有尚未到达的点.
找到一个矩形中所有未到达的点,可以用线段树套set实现
Code
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <set>
#include <vector>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define lson u<<1,l,mid
#define rson u<<1|1,mid+1,r
#define fi first
#define se second
using namespace std;
inline char gc() {
static char buf[100000],*l=buf,*r=buf;
return l==r&&(r=(l=buf)+fread(buf,1,100000,stdin),l==r)?EOF:*l++;
}
template<class T> void rd(T &x) {
x=0; int f=1,ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10-'0'+ch;ch=gc();}
x*=f;
}
const int inf=2e9;
const int maxn=7e4+50,maxm=1.5e5+50;
int n,m,w,h,t[maxm],L[maxm],R[maxm],U[maxm],D[maxm];
int an[maxn],dis[maxm];
vector<int> adj[maxn];
namespace seg {
const int maxnode=maxn<<2;
set< pair<int,int> > s[maxnode];
void update(int u,int l,int r,int qp,pair<int,int> qv) {
s[u].insert(qv);
if(l==r) return;
int mid=(l+r)>>1;
if(qp<=mid) update(lson,qp,qv);
else update(rson,qp,qv);
}
int query(int u,int l,int r,int ql,int qr,int a,int b) {
if(l==ql&&r==qr) {
while(true) {
set< pair<int,int> >::iterator it=s[u].lower_bound(make_pair(a,0));
if(it==s[u].end()||it->fi>b) return -1;
if(an[it->se]!=-1) s[u].erase(it);
else return it->se;
}
}
int mid=(l+r)>>1;
if(qr<=mid) return query(lson,ql,qr,a,b);
else if(ql>mid) return query(rson,ql,qr,a,b);
else {
int re=query(lson,ql,mid,a,b);
if(re==-1) re=query(rson,mid+1,qr,a,b);
return re;
}
}
}
void dijkstra(int st) {
priority_queue< pair<int,int> > q;
memset(an,-1,sizeof(an));
for(int i=1;i<=m;++i) dis[i]=inf;
an[st]=0;
for(int i=0;i<adj[st].size();++i) {
int e=adj[st][i];
dis[e]=t[e];
q.push(make_pair(-dis[e],e));
}
while(!q.empty()) {
int e=q.top().se; q.pop();
while(true) {
int u=seg::query(1,1,w,L[e],R[e],U[e],D[e]); if(u==-1) break;
an[u]=dis[e];
for(int i=0;i<adj[u].size();++i) {
int e=adj[u][i];
dis[e]=an[u]+t[e];
q.push(make_pair(-dis[e],e));
}
}
}
}
int main() {
freopen("jump.in","r",stdin);
freopen("jump.out","w",stdout);
rd(n),rd(m),rd(w),rd(h);
for(int i=1;i<=n;++i) {
int x,y; rd(x),rd(y);
seg::update(1,1,w,x,make_pair(y,i));
}
for(int i=1;i<=m;++i) {
int p; rd(p),rd(t[i]),rd(L[i]),rd(R[i]),rd(U[i]),rd(D[i]);
adj[p].push_back(i);
}
dijkstra(1);
for(int i=2;i<=n;++i) printf("%d\n",an[i]);
return 0;
}