• 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
    ",an[i]);
    	return 0;
    } 
    
  • 相关阅读:
    Android Wear真机蓝牙调试方法及错误解决方法,设备华为WATCH+小米5
    Ubuntu16.04 Selenium+python 环境搭建 Chromedriver安装
    Ubuntu16.04 为vim安装YouCompleteMe插件
    codeforces 676C Vasya and String 贪心 尺取法
    poj 1177 & hdu 1828 Picture 线段树 扫描线求矩形周长并
    hdu 1542 & poj 1151 Atlantis 线段树扫描线求矩形面积并
    fzu 2109 Mountain Number 数位DP
    fzu 2105 Digits Count 线段树
    codeforces 675D Tree Construction 数据结构
    codeforces 675C Money Transfers 贪心
  • 原文地址:https://www.cnblogs.com/ljzalc1022/p/13267893.html
Copyright © 2020-2023  润新知