loj 3159 [NOI2019]弹跳

loj 3159 [NOI2019]弹跳

https://loj.ac/problem/3159

UVgAOS.png

UVg9JI.png

UVgnFs.png

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;
} 
posted @ 2020-07-08 16:54  LJZ_C  阅读(95)  评论(0编辑  收藏  举报