zoukankan      html  css  js  c++  java
  • loj2090 「ZJOI2016」旅行者

    分治+最短路,很套路的

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    using namespace std;
    int n, m, ans[100005], px[20005], py[20005], uu, hea[20005], cnt, q, din;
    int dis[20005];
    bool vis[20005];
    struct Edge{
    	int too, nxt, val;
    }edge[1000005];
    struct Ques{
    	int xu, yu, xv, yv, id;
    }qu[100005], qq[100005];
    struct Node{
    	int idx, dis;
    }nd[5000005];
    int f(int x, int y){
    	return (x-1)*m+y;
    }
    void add_edge(int fro, int too, int val){
    	edge[++cnt].nxt = hea[fro];
    	edge[cnt].too = too;
    	edge[cnt].val = val;
    	hea[fro] = cnt;
    }
    bool inn(int x, int nl, int nr, int ml, int mr){
    	if(px[x]>=nl && px[x]<=nr && py[x]>=ml && py[x]<=mr)
    		return true;
    	return false;
    }
    bool cmp(Node x, Node y){
    	return x.dis>y.dis;
    }
    void dijkstra(int x, int nl, int nr, int ml, int mr){
    	for(int i=nl; i<=nr; i++)
    		for(int j=ml; j<=mr; j++){
    			dis[f(i,j)] = 0x3f3f3f3f;
    			vis[f(i,j)] = false;
    		}
    	dis[x] = 0;
    	din = 1;
    	nd[1] = (Node){x, 0};
    	while(din){
    		int o=nd[1].idx;
    		pop_heap(nd+1, nd+1+din, cmp);
    		din--;
    		if(vis[o])	continue;
    		vis[o] = true;
    		for(int i=hea[o]; i; i=edge[i].nxt){
    			int t=edge[i].too;
    			if(inn(t, nl, nr, ml, mr) && dis[t]>dis[o]+edge[i].val){
    				dis[t] = dis[o] + edge[i].val;
    				nd[++din] = (Node){t, dis[t]};
    				push_heap(nd+1, nd+1+din, cmp);
    			}
    		}
    	}
    }
    void solve(int nl, int nr, int ml, int mr, int ql, int qr){
    	if(ql>qr)	return ;
    	if(nr-nl>mr-ml){
    		int mid=(nl+nr)>>1;
    		for(int i=ml; i<=mr; i++){
    			int p=f(mid, i);
    			dijkstra(p, nl, nr, ml, mr);
    			for(int j=ql; j<=qr; j++)
    				ans[qu[j].id] = min(ans[qu[j].id], dis[f(qu[j].xu, qu[j].yu)]+dis[f(qu[j].xv, qu[j].yv)]);
    		}
    		int l=ql, r=qr;
    		for(int i=ql; i<=qr; i++)
    			if(qu[i].xu<mid && qu[i].xv<mid)	qq[l++] = qu[i];
    			else if(qu[i].xu>mid && qu[i].xv>mid)	qq[r--] = qu[i];
    		for(int i=ql; i<=qr; i++)
    			qu[i] = qq[i];
    		solve(nl, mid-1, ml, mr, ql, l-1);
    		solve(mid+1, nr, ml, mr, r+1, qr);
    	}
    	else{
    		int mid=(ml+mr)>>1;
    		for(int i=nl; i<=nr; i++){
    			int p=f(i, mid);
    			dijkstra(p, nl, nr, ml, mr);
    			for(int j=ql; j<=qr; j++)
    				ans[qu[j].id] = min(ans[qu[j].id], dis[f(qu[j].xu, qu[j].yu)]+dis[f(qu[j].xv, qu[j].yv)]);
    		}
    		int l=ql, r=qr;
    		for(int i=ql; i<=qr; i++)
    			if(qu[i].yu<mid && qu[i].yv<mid)	qq[l++] = qu[i];
    			else if(qu[i].yu>mid && qu[i].yv>mid)	qq[r--] = qu[i];
    		for(int i=ql; i<=qr; i++)
    			qu[i] = qq[i];
    		solve(nl, nr, ml, mid-1, ql, l-1);
    		solve(nl, nr, mid+1, mr, r+1, qr);
    	}
    }
    int main(){
    	memset(ans, 0x3f, sizeof(ans));
    	cin>>n>>m;
    	for(int i=1; i<=n; i++)
    		for(int j=1; j<m; j++){
    			scanf("%d", &uu);
    			int p=f(i,j), q=f(i,j+1);
    			add_edge(p, q, uu);
    			add_edge(q, p, uu);
    		}
    	for(int i=1; i<n; i++)
    		for(int j=1; j<=m; j++){
    			scanf("%d", &uu);
    			int p=f(i,j), q=f(i+1,j);
    			add_edge(p, q, uu);
    			add_edge(q, p, uu);
    		}
    	for(int i=1; i<=n; i++)
    		for(int j=1; j<=m; j++){
    			int p=f(i,j);
    			px[p] = i;
    			py[p] = j;
    		}
    	cin>>q;
    	for(int i=1; i<=q; i++){
    		scanf("%d %d %d %d", &qu[i].xu, &qu[i].yu, &qu[i].xv, &qu[i].yv);
    		qu[i].id = i;
    	}
    	solve(1, n, 1, m, 1, q);
    	for(int i=1; i<=q; i++)
    		printf("%d
    ", ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    4.Eclipse下的Hadoop开发实践
    6.命令行编译打包运行五个MapReduce程序
    1.Hadoop初步环境搭建(ssh无密码通信)
    webkit中对incomplete type指针的处理技巧
    Windows平台编译Webkit
    利用Webkit抓取动态网页和链接
    用C#实现网络爬虫(一)
    C#中delegate对象Equals方法简析
    Webkit客户端进程解析
    用C#实现网络爬虫(二)
  • 原文地址:https://www.cnblogs.com/poorpool/p/9050701.html
Copyright © 2011-2022 走看看