• 【LOJ】#2090. 「ZJOI2016」旅行者


    题解

    每次按较长边把矩形分成两半,找一个中间轴,轴上的每个点跑一边最短路更新所有的答案

    然后把矩形分成两半,递归下去

    代码

    #include <bits/stdc++.h>
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define eps 1e-8
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9') {
            res = res * 10 - '0' + c;
            c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) out(x / 10);
        putchar('0' + x % 10);
    }
    int N,M,Q;
    int id(int x,int y) {return (x - 1) * M + y;}
    pii point(int s) {return mp((s - 1) / M + 1,(s - 1) % M + 1);}
    struct qry_node {
    	int s,t,id;
    }qry[100005],tmp[100005];
    struct node {
    	int to,next,val;
    }E[200005];
    int head[20005],sumE;
    int R[20005],C[20005],ans[100005],dis[20005];
    bool vis[20005];
    priority_queue<pii > que;
    void add(int u,int v,int c) {
    	E[++sumE].to = v;
    	E[sumE].next = head[u];
    	E[sumE].val = c;
    	head[u] = sumE;
    }
    bool in_Matrix(int x,int X1,int Y1,int X2,int Y2) {
    	pii p = point(x);
    	return p.fi >= X1 && p.fi <= X2 && p.se >= Y1 && p.se <= Y2;
    }
    void Dijkstra(int st,int X1,int Y1,int X2,int Y2) {
    	for(int i = X1 ; i <= X2 ; ++i) {
    		for(int j = Y1 ; j <= Y2 ; ++j) {
    			dis[id(i,j)] = 0x7fffffff;
    			vis[id(i,j)] = 0;
    		}
    	}
    	dis[st] = 0;
    	que.push(mp(-dis[st],st));
    	while(!que.empty()) {
    		pii now = que.top();que.pop();
    		if(vis[now.se]) continue;
    		vis[now.se] = 1;
    		int u = now.se;
    		for(int i = head[u] ; i ; i = E[i].next) {
    			int v = E[i].to;
    			if(!vis[v] && in_Matrix(v,X1,Y1,X2,Y2) && dis[v] > dis[u] + E[i].val) {
    				dis[v] = dis[u] + E[i].val;
    				que.push(mp(-dis[v],v));
    			}
    		}
    	}
    }
    void update(int &x,int y) {
    	x = min(x,y);
    }
    void Solve(int l,int r,int X1,int Y1,int X2,int Y2) {
    	if(Y1 > Y2 || X1 > X2) return;
    	if(Y1 == Y2 && X1 == X2) return;
    	if(l > r) return;
    	if(X2 - X1 <= Y2 - Y1) {
    		int mid = (Y2 + Y1) >> 1;
    		for(int i = X1 ; i <= X2 ; ++i) {
    			Dijkstra(id(i,mid),X1,Y1,X2,Y2);
    			for(int k = l ; k <= r ; ++k) {
    				update(ans[qry[k].id],dis[qry[k].s] + dis[qry[k].t]);
    			}
    		}
    		int p = l - 1,m = l - 1;
    		for(int k = l ; k <= r ; ++k) {
    			if(in_Matrix(qry[k].s,X1,Y1,X2,mid - 1) && in_Matrix(qry[k].t,X1,Y1,X2,mid - 1)) {
    				tmp[++p] = qry[k];
    			}
    		}
    		m = p;
    		for(int k = l ; k <= r ; ++k) {
    			if(in_Matrix(qry[k].s,X1,mid + 1,X2,Y2) && in_Matrix(qry[k].t,X1,mid + 1,X2,Y2)) {
    				tmp[++p] = qry[k];
    			}
    		}
    		for(int i = l ; i <= p ; ++i) qry[i] = tmp[i];
    		Solve(l,m,X1,Y1,X2,mid - 1);
    		Solve(m + 1,p,X1,mid + 1,X2,Y2);
    	}
    	else {
    		int mid = (X1 + X2) >> 1;
    		for(int j = Y1 ; j <= Y2 ; ++j) {
    			Dijkstra(id(mid,j),X1,Y1,X2,Y2);
    			for(int k = l ; k <= r ; ++k) {
    				update(ans[qry[k].id],dis[qry[k].s] + dis[qry[k].t]);
    			}
    		}
    		int p = l - 1,m = l - 1;
    		for(int k = l ; k <= r ; ++k) {
    			if(in_Matrix(qry[k].s,X1,Y1,mid - 1,Y2) && in_Matrix(qry[k].t,X1,Y1,mid - 1,Y2)) {
    				tmp[++p] = qry[k];
    			}
    		}
    		m = p;
    		for(int k = l ; k <= r ; ++k) {
    			if(in_Matrix(qry[k].s,mid + 1,Y1,X2,Y2) && in_Matrix(qry[k].t,mid + 1,Y1,X2,Y2)) {
    				tmp[++p] = qry[k];
    			}
    		}
    		for(int i = l ; i <= p ; ++i) qry[i] = tmp[i];
    		Solve(l,m,X1,Y1,mid - 1,Y2);
    		Solve(m + 1,p,mid + 1,Y1,X2,Y2);
    	}
    }
    void Init() {
    	read(N);read(M);
    	for(int i = 1 ; i <= N ; ++i) {
    		for(int j = 1 ; j <= M - 1; ++j) {
    			read(R[id(i,j)]);
    			add(id(i,j),id(i,j + 1),R[id(i,j)]);
    			add(id(i,j + 1),id(i,j),R[id(i,j)]);
    		}
    	}
    	for(int i = 1 ; i <= N - 1 ; ++i) {
    		for(int j = 1 ; j <= M ; ++j) {
    			read(C[id(i,j)]);
    			add(id(i,j),id(i + 1,j),C[id(i,j)]);
    			add(id(i + 1,j),id(i,j),C[id(i,j)]);
    		}
    	}
    	read(Q);
    	int x,y;
    	for(int i = 1 ; i <= Q ; ++i) {
    		read(x);read(y);qry[i].s = id(x,y);
    		read(x);read(y);qry[i].t = id(x,y);
    		qry[i].id = i;
    		ans[i] = 0x7fffffff;
    		if(qry[i].s == qry[i].t) ans[i] = 0;
    	}
    
    }
    int main() {
    #ifdef ivorysi
    	freopen("f1.in","r",stdin);
    #endif
    	Init();
    	Solve(1,Q,1,1,N,M);
    	for(int i = 1 ; i <= Q ; ++i) {out(ans[i]);enter;}
    }
    
  • 相关阅读:
    kubeadm部署k8s v1.18.6版本
    harbor
    kubectl常用命令
    日常运维知识点
    CentOS6.5搭建oracle11g RAC
    linux(mint)下刻录镜像到光盘
    aspectj
    NoSql系列目录
    在线考试系统源码(题库抽题&自动阅卷打分)
    java问卷调查系统源码(java+mysql)
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9569791.html
Copyright © 2020-2023  润新知