题目链接:https://codeforces.com/gym/102021/attachments

题意:现在有个地图由n∗mn*mn∗m个方格组成,每个方格上有个数字,代表在这个点的海拔高度,现在qqq次询问,每次询问给出两个点,你需要找到一条路径可以由一个点走到另一个点并且要求这条路径上的最高海拔要尽可能的小,输出每次询问的最小的最大高度。从一个点只能走到这个点的四个方向。

解题心得:这个题只能将点加入然后用并查集维护可以走到的点这样才能满足复杂度,在放入点的时候需要将每个点按照高度排序,从小到大放入,在合并并查集的时候需要启发式合并。


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 1010;int num[maxn][maxn], n, m, q, que[maxn][maxn], ans[maxn*maxn];
int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
struct Point {int x, y, va;bool operator < (const Point & p) const {return va < p.va;}
};struct Node {int fa;set<int> se;
}node[maxn*maxn];vector <Point> ve;int Hash(int x, int y) {return (x-1)*m + y;
}void init() {scanf("%d%d%d",&n, &m, &q);for(int i=1;i<=n;i++) {for(int j=1;j<=m;j++) {scanf("%d", &num[i][j]);ve.push_back({i, j, num[i][j]});node[Hash(i, j)].fa = Hash(i, j);}}sort(ve.begin(), ve.end());for(int i=1;i<=q;i++) {int x1, x2, y1, y2;scanf("%d%d%d%d",&x1, &y1, &x2, &y2);if(x1 == x2 && y1 == y2) {ans[i] = num[x1][y1];continue;}que[x1][y1] = i;que[x2][y2] = i;node[Hash(x1, y1)].se.insert(i);node[Hash(x2, y2)].se.insert(i);}}bool checke(int x,int y) {if(x <= 0 || y <= 0 || x > n || y > m) return true;return false;
}int find(int x) {if(x == node[x].fa) return x;else return node[x].fa = find(node[x].fa);
}void merge(int x, int y, int Ans) {int fx = find(x);int fy = find(y);if(fx == fy) return ;int cnt1 = node[fx].se.size(), cnt2 = node[fy].se.size();if(cnt1 <= cnt2) {set <int> :: iterator iter, iter2;for(iter=node[fx].se.begin();iter!=node[fx].se.end();iter++) {int va = (*iter);iter2 = node[fy].se.find(va);if(iter2 == node[fy].se.end()) {node[fy].se.insert(va);} else {ans[va] = Ans;node[fy].se.erase(iter2);}}node[fx].fa = node[fy].fa;} else {set <int> :: iterator iter, iter2;for(iter=node[fy].se.begin();iter!=node[fy].se.end();iter++) {int va = (*iter);iter2 = node[fx].se.find(va);if(iter2 == node[fx].se.end()) {node[fx].se.insert(va);} else {ans[va] = Ans;node[fx].se.erase(iter2);}}node[fy].fa = node[fx].fa;}
}void solve() {for(int i=0;i<ve.size();i++) {Point now = ve[i];int va = now.va;int nx, ny;for(int i=0;i<4;i++) {nx = now.x + dir[i][0];ny = now.y + dir[i][1];if(checke(nx, ny)) continue;if(num[nx][ny] > num[now.x][now.y]) continue;int num1 = Hash(now.x, now.y);int num2 = Hash(nx, ny);merge(num1, num2, va);}}
}int main() {//    freopen("1.in.txt", "r", stdin);init();solve();for(int i=1;i<=q;i++) {printf("%d\n", ans[i]);}return 0;
}

2018 German Collegiate Programming Contest (GCPC 18) M - Mountaineers(启发式合并)相关推荐

  1. 2018 German Collegiate Programming Contest (GCPC 18)

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

  2. 2021 HZNU Winter Training Day 17 (2018 German Collegiate Programming Contest (GCPC 18))

    2021 HZNU Winter Training Day 17 (2018 German Collegiate Programming Contest (GCPC 18)) 题目 A B C D E ...

  3. (寒假开黑gym)2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017)

    layout: post title: (寒假开黑gym)2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017) au ...

  4. 2015 German Collegiate Programming Contest (GCPC 15)

    2015 German Collegiate Programming Contest (GCPC 15) B. Bounty Hunter II 给定一张DAG,求一种方案:用最少的路径将所有点覆盖. ...

  5. 2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017)

    A Drawing Borders 很多构造方法,下图可能是最简单的了 代码: #include<bits/stdc++.h> using namespace std; const int ...

  6. 2018 Arab Collegiate Programming Contest (ACPC 2018) G. Greatest Chicken Dish (线段树+GCD)

    题目链接:https://codeforces.com/gym/101991/problem/G 题意:给出 n 个数,q 次询问区间[ li,ri ]之间有多少个 GCD = di 的连续子区间. ...

  7. 2018 Arab Collegiate Programming Contest (ACPC 2018) E - Exciting Menus AC自动机

    E - Exciting Menus 建个AC自动机求个fail指针就好啦. #include<bits/stdc++.h> #define LL long long #define fi ...

  8. 2018 Arab Collegiate Programming Contest (ACPC 2018) H - Hawawshi Decryption 数学 + BSGS

    H - Hawawshi Decryption 对于一个给定的生成数列 R[ 0 ] 已知, (R[ i - 1 ] * a + b) % p = R[ i ] (p 是 质数), 求最小的 x 使得 ...

  9. 2018 Arab Collegiate Programming Contest (ACPC 2018) L.Looking for Taste(按位或)

    题目 n个数选k个,使它们的或最大 n<=1e5 k>=20 ai<=1e6 题解 从高向低位或, 每个数至少产生一位的贡献,所以最多20个数 贪心地使或的数最大即可 由于或没有副作 ...

最新文章

  1. BC:带你温习并解读《中国区块链技术和应用发展白皮书》—区块链技术发展路线图
  2. C++二维数组按行遍历和按列遍历的区别
  3. Trie树(字典树)详细知识点及其应用
  4. hadoop 批流处理的实现_从T+1到T+0,浅谈PetaBase的实时流式处理
  5. node.js中使用https请求报CERT_UNTRUSTED的问题解决
  6. 谷歌发布Edge TPU芯片,云上模型本地运行丨附尝鲜地址
  7. 华尔街日报:微软告别盖茨时代
  8. Http client to POST using multipart/form-data
  9. 【Unity3D插件】AnyPortrait插件分享《(一)制作史莱姆动画》
  10. 性能效率(Performance efficient)弱点度量
  11. x86 实模式与保护模式
  12. markdown中划线
  13. js获取服务器响应时间,【JS】浏览器所允许的http请求最长的响应时间?
  14. ZOJ 1516 Uncle Tom's Inherited Land
  15. C51中的INTRINS.H:内部函数
  16. rockchip研讨会_地下在线研讨会6
  17. offsetTop和scrollTop区别
  18. Thrift in python
  19. 【播客】对话赵赵:美国大城市的死与生与社区建设
  20. 金融债券定价公式:假设你买了一只50年期债券,票面利率是6%,面值是1000元,每半年付息一次。如果该债券的必要报酬率是3%,那么这个债券的价格应当是多少?

热门文章

  1. 如何选择香港虚拟主机
  2. 自动化测试--20验证码识别
  3. OpenJudge NOI 2.1 2983:谁是你的潜在朋友
  4. PAC(Proxy Auto Config)代理自动配置文件的编写
  5. 通过统一多模态Transformer(UMT)的实体扫描检测(ESD)来改进多模态命名实体识别(MNER)
  6. 2022危险化学品经营单位安全管理人员考试题库及在线模拟考试
  7. 【大并发服务器开发】简要谈谈分布式服务器的设计方案思路推变过程
  8. Jetson Nano入坑笔记(一)
  9. matlab的时域信号计算,matlab – 计算时域数据的能量
  10. INSERT INTO 和 INSERT IGNORE INTO