zoukankan      html  css  js  c++  java
  • 题解 [NOI2019]弹跳

    题目传送门

    题目大意

    给出 (n) 做城市,每座城市都有横纵坐标 (x,y)。现在给出 (m) 个限制 (p,t,l,r,d,u),表示从 (p) 城市出发,可以花费 (t) 走到 (lle xle r,dle yle u) 的一座城市。

    问,从城市 1 出发走到每座城市的最小花费是多少?

    (nle 7 imes 10^4,mle 1.5 imes 10^5)

    思路

    这道题自己只做出来 (76) 分,剩下的感觉还是比较妙吧?

    首先不难看出,我们可以用 K-D Tree 优化建图,大概意思就是 K-D Tree 上的虚点连对应的实点,虚点连儿子,每个点连可以到的点的虚点,然后跑最短路算法就好了。

    这样做可以看出边数是 (msqrt n) 级别的,所以时间复杂度是 (Theta(msqrt nlog n)),但是空间复杂度也是 (msqrt n) 级别的。

    我们其实可以考虑不建边,每次在 K-D Tree 上进行松弛操作。这样空间复杂度就降到了 (n+m)

    ( exttt{Code})

    #include <bits/stdc++.h>
    using namespace std;
    
    #define Int register int
    #define MAXN 140005
    
    template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
    template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
    template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
    
    int n,m,w,h,rt,cut;
    
    struct Vector{
    	int x[2],pos;
    	bool operator < (const Vector &p)const{return x[cut] < p.x[cut];}
    }city[MAXN],pnt[MAXN];
    int mi[MAXN][2],mx[MAXN][2],lson[MAXN],rson[MAXN];
    
    void Mx (int &a,int b){a = max (a,b);}
    void Mi (int &a,int b){a = min (a,b);}
    void Pushup (int x){
    	mi[x][0] = mx[x][0] = city[x].x[0],mi[x][1] = mx[x][1] = city[x].x[1];
    	if (lson[x]) for (Int i = 0;i < 2;++ i) Mi (mi[x][i],mi[lson[x]][i]),Mx (mx[x][i],mx[lson[x]][i]);
    	if (rson[x]) for (Int i = 0;i < 2;++ i) Mi (mi[x][i],mi[rson[x]][i]),Mx (mx[x][i],mx[rson[x]][i]);
    }
    
    int build (int l,int r,int k){
    	if (l > r) return 0;
    	int mid = (l + r) >> 1,now = mid;cut = k;
    	nth_element (city + l,city + mid,city + r + 1);
    	if (l == r) return Pushup (now),now;
    	else{
    		lson[now] = build (l,mid - 1,k ^ 1);
    		rson[now] = build (mid + 1,r,k ^ 1);
    	}
    	Pushup (now);
    	return now; 
    }
    
    int dist[MAXN];
    bool vis[MAXN];
    #define PII pair<int,int>
    priority_queue <PII,vector <PII>,greater <PII> > q; 
    
    void Relax (int u,int w){
    	if (dist[u] > w){
    		dist[u] = w;
    		if (!vis[u]) q.push (make_pair (dist[u],u));
    	}
    }
    
    void SolveE (int now,int x1,int x2,int y1,int y2,int ind,int t){
    	if (!now) return ;
    	if (mi[now][0] > x2 || mx[now][0] < x1 || mi[now][1] > y2 || mx[now][1] < y1) return ;
    	if (mi[now][0] >= x1 && mx[now][0] <= x2 && mi[now][1] >= y1 && mx[now][1] <= y2){
    		Relax (now,dist[ind] + t);
    		return ;
    	}
    	if (city[now].x[0] >= x1 && city[now].x[0] <= x2 && city[now].x[1] >= y1 && city[now].x[1] <= y2) 
    		Relax (city[now].pos,dist[ind] + t);
    	SolveE (lson[now],x1,x2,y1,y2,ind,t);
    	SolveE (rson[now],x1,x2,y1,y2,ind,t);
    	return ;
    } 
    
    struct node{int L,R,U,D,T;};
    vector <node> G[MAXN];
    
    void Dijkstra (int s){
    	memset (dist,0x7f,sizeof (dist));
    	dist[s] = 0,vis[s] = 1;
    	while (!q.empty()) q.pop ();
    	q.push (make_pair (0,s)); 
    	while (!q.empty()){
    		PII now = q.top ();q.pop ();int u = now.second;vis[u] = 1;
    		if (dist[u] != now.first) continue;
    		if (u > n) for (node to : G[u - n]) SolveE (rt,to.L,to.R,to.D,to.U,u,to.T);
    		else Relax (lson[u],dist[u]),Relax (rson[u],dist[u]),Relax (city[u].pos,dist[u]);
    	}
    }
    
    signed main(){
    	read (n,m,w,h);
    	for (Int i = 1;i <= n;++ i) read (city[i].x[0],city[i].x[1]),city[i].pos = n + i;
    	rt = build (1,n,0);for (Int i = 1;i <= m;++ i){
    		int p,t,l,r,d,u;read (p,t,l,r,d,u);
    		G[p].push_back (node {l,r,u,d,t});
    	}
    	Dijkstra (n + 1);
    	for (Int i = 2;i <= n;++ i) write (dist[n + i]),putchar ('
    ');
    	return 0;
    }
    
  • 相关阅读:
    LeetCode数据库178
    LeetCode数据库181
    LeetCode数据库177
    LeetCode数据库176
    HNOI2003 消防局的设立
    HNOI2001 产品加工
    Luogu P1020 关路灯
    NOIP2004 虫食算
    SP2713 GSS4-Can you answer these queries IV
    APIO2008 免费道路
  • 原文地址:https://www.cnblogs.com/Dark-Romance/p/13777386.html
Copyright © 2011-2022 走看看