Mountaineers

时间限制: 3 Sec  内存限制: 128 MB

题目描述

The Chilean Andes have become increasingly popular as a destination for backpacking and hiking. Many parts of the Andes are quite remote and thus dangerous. Because of this, the Ministry of Tourism wants to help travelers plan their trips. In particular, the travelers need to know how high they will have to climb during their journey, as this information will help them decide which equipment they need to bring. The Ministry has tasked you to provide the aspiring mountaineers with this data.
You are given a topographic map of a part of the Andes, represented as a two-dimensional grid of height values, as well as the list of origins and destinations. Mountaineers can move from each grid cell to any of the four adjacent cells. For each mountaineer find the minimal height that they must be able to reach in order to complete their journey.

输入

The input consists of:
•one line with three integers m, n and q (1 ≤ m, n ≤ 500, 1 ≤ q ≤ 105), where m is the number of rows, n is the number of columns, and q is the number of mountaineers;
•m lines, each with n integers h1, ... , hn (1 ≤ hi ≤ 106), the height values in the map;
•q lines, each with four integers x1, y1, x2, y2 (1 ≤ x1, x2 ≤ m, 1 ≤ y1, y2 ≤ n), describing a mountaineer who wants to trek from (x1, y1) to (x2, y2).
The top left cell of the grid has coordinates (1, 1) and the bottom right cell has coordinates (m, n).

输出

Output q integers, the minimal height for each mountaineer, in the same order as in the input.

样例输入

3 5 3
1 3 2 1 3
2 4 5 4 4
2 1 3 2 2
1 1 3 2
2 4 2 2
1 4 3 4

样例输出

2
4
3

来源/分类

GCPC2018


题意:有一个m*n的图,图中每个格子有一个数,每次询问两个格子,问从其中一个格子走到另一个格子所经过的数中,最大的那个数最小是多少。

解法:神奇的建树思想。先把全部格子对权值进行升序排序,遍历所有格子,每次遍历时把这个格子标记为已遍历,并且看看这个格子周围的格子有没有被遍历,若被遍历,则加一条有向边从当前格子指向周围格子的根结点。最后处理询问时,两个格子的lca对应的值就是此次询问的答案。(本人能力有限,给不出证明)。
#include<bits/stdc++.h>
#define N 250005
using namespace std; struct edge{int v,w;};
vector<edge>edges[N];
int grand[N][]={};
int depth[N],DEPTH,sum=; void addedge(int a,int b)
{
edges[b].push_back((edge){a});
} void dfs(int x)
{
for(int i=;i<=DEPTH;i++)
{
grand[x][i]=grand[grand[x][i-]][i-];
} for(int i=;i<edges[x].size();i++)
{
int to=edges[x][i].v;
if(grand[x][]==to)continue; depth[to]=depth[x]+;
grand[to][]=x;
dfs(to);
}
} void init(int s)
{
DEPTH=floor(log(sum + 0.0) / log(2.0));
depth[s]=; //注意根节点的深度不要设为0,否则下面判深度会出错
memset(grand,,sizeof(grand));
dfs(s);
} int lca(int a,int b)
{
if(depth[a]>depth[b])swap(a,b); for(int i=DEPTH;i>=;i--)
if(depth[a]<depth[b]&&depth[grand[b][i]]>=depth[a])
b=grand[b][i]; for(int i=DEPTH;i>=;i--)
if(grand[a][i]!=grand[b][i])
{
a=grand[a][i];
b=grand[b][i];
} if(a!=b)
{
return grand[a][];
}
return a;
} int pre[]; int Find(int x)
{
int boss=x;
while(boss!=pre[boss])boss=pre[boss]; int temp;
while(x!=pre[x])
{
temp=pre[x];
pre[x]=boss;
x=temp;
}
return boss;
} struct ss
{
int x,y,value,number; bool operator < (const ss &s) const
{
return value<s.value;
} };
ss arr[];
int vis[][]={};
int ans[]; int main()
{ int m,n,q,s;
scanf("%d %d %d",&m,&n,&q);
for(int i=;i<=m*n;i++)pre[i]=i; for(int i=;i<=m;i++)
for(int j=;j<=n;j++)
{
scanf("%d",&arr[sum].value);
arr[sum].x=i;
arr[sum].y=j;
arr[sum].number=sum;
ans[sum]=arr[sum].value;
sum++;
} sort(arr+,arr+sum);
for(int i=;i<sum;i++)
{
int x=arr[i].x,y=arr[i].y,num=arr[i].number;
vis[x][y]=num;
s=num; if(x->=&&vis[x-][y]&&Find(vis[x-][y])!=num)
{
addedge(Find(vis[x-][y]),num);
pre[Find(vis[x-][y])]=num;
} if(x+<=m&&vis[x+][y]&&Find(vis[x+][y])!=num)
{
addedge(Find(vis[x+][y]),num);
pre[Find(vis[x+][y])]=num;
} if(y->=&&vis[x][y-]&&Find(vis[x][y-])!=num)
{
addedge(Find(vis[x][y-]),num);
pre[Find(vis[x][y-])]=num;
} if(y+<=n&&vis[x][y+]&&Find(vis[x][y+])!=num)
{
addedge(Find(vis[x][y+]),num);
pre[Find(vis[x][y+])]=num;
} } init(s); while(q--)
{
int a,b,c,d;
scanf("%d %d %d %d",&a,&b,&c,&d);
a--;
c--;
printf("%d\n",ans[lca(a*n+b,c*n+d)]);
}
return ;
}

Mountaineers的更多相关文章

  1. Mountaineers Gym - 102021M (LCA+MST)

    题目链接: Mountaineers  Gym - 102021M 题目大意:给你一个n*m的矩阵,a[i][j]代表当前方块的高度,然后每次询问给你一个起点和终点,然后问你在这个图上你选择一条路径, ...

  2. Cheap Hollister Clothing

    (link to hollisterco site), Spectacles don't simply take care of the eye area inside sun; Putting th ...

  3. 2018 German Collegiate Programming Contest (GCPC 18)

    2018 German Collegiate Programming Contest (GCPC 18) Attack on Alpha-Zet 建树,求lca 代码: #include <al ...

  4. Python3自然语言(NLTK)——语言大数据

    NLTK 这是一个处理文本的python库,我们知道文字性的知识可是拥有非常庞大的数据量,故而这属于大数据系列. 本文只是浅尝辄止,目前本人并未涉及这块知识,只是偶尔好奇,才写本文. 从NLTK中的b ...

  5. Gym .102021 .German Collegiate Programming Contest (GCPC 18) (寒假gym自训第三场)

    B .Battle Royale 题意:给你两个点A,B,以及一个圆S,保证两个点在圆外,且其连线与圆相交,求两点间最短距离. 思路:显然是要分别与圆相切,然后在圆弧想走,直到相交. 那么ans=与圆 ...

  6. L164

    “TAKE ONLY memories, leave only footprints” is more than a hiking motto at the Sagarmatha National P ...

随机推荐

  1. 《算法图解》中涉及的算法的总结及java实现

    该项目源代码已经放到Github上,有兴趣可以点击AlgorithmGraphExample 进行访问 项目启动,项目使用maven搭建,如果不使用maven导入,请保证有Junit4的jar包在工程 ...

  2. MINST手写数字识别(一)—— 全连接网络

    这是一个简单快速入门教程——用Keras搭建神经网络实现手写数字识别,它大部分基于Keras的源代码示例 minst_mlp.py. 1.安装依赖库 首先,你需要安装最近版本的Python,再加上一些 ...

  3. kitti raw data development kit的使用

    run_demoVelodyne.m使用:http://blog.csdn.net/qq_33801763/article/details/78959205   https://www.cnblogs ...

  4. vue 获取汉字的全拼、简拼、首拼

    1.封装公共方法,获取汉字的全拼.简拼.首拼 export const Pinyin = { _JMcode:{ "-":"", "—":& ...

  5. EF关于报错Self referencing loop detected with type的原因以及解决办法

    1)具体报错 { "Message": "出现错误.", "ExceptionMessage": "“ObjectContent` ...

  6. Java中的线程--线程的互斥与同步通信

    Java中的线程之前也提到过,但是还是想再详细的学习一下,跟着张孝祥老师,系统的再学习一下. 一.线程中的互斥 线程安全中的问题解释:线程安全问题可以用银行中的转账 例题描述: 线程A与线程B分别访问 ...

  7. Bootstrap历练实例:弹出提示信息的样式按钮

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  8. vue 封装分页组件

    分页 一般都是调接口, 接口为这种格式 {code: 0, msg: "success",…} code:0 data:{ content:[{content: "11& ...

  9. codevs 数字三角形集结

    添在前面的一句话:初学DP,若有错误,请指出,不能误人子弟,欢迎大家提出意见.水平不高,博客写的比较粗糙,代码也挺丑,请见谅. 最原始的数字三角形: 1220 数字三角形  时间限制: 1 s  空间 ...

  10. [LUOGU] 1002 过河卒

    题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为"马拦过 ...