这道题要逆向思维

反过来从大到小枚举, 就是在矩阵中一点一点加进去数字,这样比较

好操作, 如果正着做就要一点一点删除数字, 不好做。

我们需要在这个过程中维护联通块的个数, 这里用到了并查集。

首先加进去一个数, 联通分量数字先加一, 然后再考虑有没有和其他联通分量

相连。从当前位置四个方向枚举, 如果这个数之前已经被选中, 同时

不是一个联通分量, 那么也就是说当前这个木块把两个联通分量变成一个

联通分量, 联通分量数减去一。

这里还要把二维的化为一维的编号, 方便并查集操作。

然后注意这里输出很奇怪, 最后输出一行的最后一个位置是要有空格的

不然会格式错误。

#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;const int MAXN = 1123456;
struct node
{int x, y, v;bool operator < (const node& rhs) const{return v < rhs.v;}
};
vector<node> nodes;
int a[MAXN], ans[MAXN], n, m, k, sum;
int vis[MAXN], f[MAXN];
int dir[4][2] = {0, 1, 0, -1, -1, 0, 1, 0};int find(int x)
{if(f[x] != x)f[x] = find(f[x]);return f[x];
}inline int ID(int x, int y) { return x * m + y; } //二维化一维 void add(node u)
{sum++;vis[ID(u.x, u.y)] = 1;REP(i, 0, 4) //判断是否和其他联通分量相连 {int xx = u.x + dir[i][0], yy = u.y + dir[i][1];if(0 <= xx && xx < n && 0 <= yy && yy < m && vis[ID(xx, yy)]) //vis的作用是之前这个数有没有被选过 {int a = find(ID(u.x, u.y)), b = find(ID(xx, yy));if(a != b) sum--, f[a] = b;}}
}int main()
{int T;scanf("%d", &T);while(T--){memset(vis, 0, sizeof(vis));nodes.clear();scanf("%d%d", &n, &m);REP(i, 0, n)REP(j, 0, m){int v;scanf("%d", &v);nodes.push_back(node{i, j, v});}scanf("%d", &k);REP(i, 0, k) scanf("%d", &a[i]); sort(nodes.begin(), nodes.end()); //把点排序,这样加数比较方便 REP(i, 0, n * m) f[i] = i;int pos = nodes.size() - 1; sum = 0;for(int i = k - 1; i >= 0; i--){while(nodes[pos].v > a[i]) add(nodes[pos--]);ans[i] = sum;}REP(i, 0, k) printf("%d ", ans[i]); //注意最后一个数字后要有空格 printf("\n");}return 0;
} 

紫书 习题 11-12 UVa 1665 (并查集维护联通分量)相关推荐

  1. 字节笔试-老c和小m之间的放书矛盾(最佳解法:并查集)

    题目描述: 老C是一位老年图书管理员,最近图书馆来了一位实习生小M.然而,由于年龄关系,老C给小M的分类图书指令有时候会是相互矛盾的.对于老C的指令,你能帮助小M判断这些指令是不是合理的.老C会给小M ...

  2. Almost Union-Find(Uva 11987)并查集

    来自<算法竞赛入门经典训练指南> 1.题目原文 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemi ...

  3. 紫书 习题 8-15 UVa 1617 (贪心)

    先排序, 然后每个线段先放右端点, 然后往下放, 如果不能放就整体往左移动, 当不能往左移动的时候就ans++ 开始下一个整块.判断能不能向左移动要用一个变量储存每个已经放了的区间中线段与左端点距离的 ...

  4. 紫书 习题 10-17 UVa 11105 (筛法)

    类似于素数筛的思想去做,不然暴力会超时而且还要判重 #include<cstdio> #include<cstring> #include<vector> #def ...

  5. 紫书 习题 10-44 UVa 11246 ( 容斥原理)

    把k的倍数的删去(k, 2k, 3k--),但是k^2不应该删去,因为k已经删去,所以不存在某个数乘上k之后为k^2 所以k^2可以留下,然后因为有k^2,所以k^3就是k^2的k倍,所以k^3要删去 ...

  6. 紫书 习题7-14 UVa 307(暴搜+剪枝)

    这道题一开始我想的是在排序之后只在头和尾往中间靠近来找木块, 然后就WA, 事实证明这种方法是错误的. 然后参考了别人的博客.发现别人是直接暴搜, 但是加了很多剪枝, 所以不会超时. 我也想过这个做法 ...

  7. 紫书 习题 10-20 UVa 1648 (推公式)

    设一次上去a层,一次下去b层,有x次上去,有(n-x)次下去 则ax - (n-x)b >= 1 x >= (nb+1) / (a+b) 如果可以整除, x = (nb+1) / (a+b ...

  8. 紫书 习题 10-7 UVa 10539(long long + 素数筛)

    注意要开long long 如果int * int会炸 那么久改成long long * int #include<cstdio> #include<vector> #incl ...

  9. 紫书 习题8-14 UVa 1616(二分+小数化分数+精度)

    参考了https://www.cnblogs.com/dwtfukgv/p/5645446.html (1)直接二分答案.说实话我没有想到, 一开始以为是贪心, 以某种策略能得到最优解. 但是想了很久 ...

最新文章

  1. 杜恩德的新博客,都来看看
  2. 实验二 二叉树的操作与实现
  3. VTK:几何对象之PlatonicSolids
  4. 杀死初创科技公司的四大工程陷阱
  5. 服务器系统怎么找便签,Win10电脑怎么找回便签记录?如何恢复误删的内容?
  6. Pythonic:递归、回溯等5种方法生成不重复数字整数
  7. 《嵌入式系统项目分析入门与实践》 读后感(1)
  8. 力压今日头条成 App Store 榜第一,个税 App 惊爆 62 例木马病毒!
  9. PHP生成有背景的二维码图,摘自网络
  10. 韦东山linux学习之ubuntu 9.10 软件源 问题
  11. 1次订单事故,扣了我3个月绩效!
  12. 构筑基于物联网操作系统的物联网生态环境【转】
  13. python暴力破解wps,Word,excel等文件
  14. android显示超图地图,超图---简单地图显示
  15. Proximal Algorithms
  16. 74CMS_v4.2.1-v4.2.129后台Getshell
  17. kill -HUP重启mysql_kill的用法和例句,包括kill常用短语解释和词组意思翻译,同义词,反义词【澳典网ODict.Net】...
  18. 2020下半年(小学)教师资格证笔试教育教学知识与能力真题与答案
  19. 日语口语1.11  松田社長がおいでになることを伺っておりまして、ずっと待っておりました
  20. 懒汉延迟加载设计模式反射注解

热门文章

  1. 计算机专业就业方向小结
  2. Latex 中导入visio画的图片,去除多余留白
  3. Quartz定时任务项目中的应用
  4. 一个生成Rockwell RSLogix5000 .csv 文件和.L5X文件的Excel插件
  5. python通过qq邮箱发邮件
  6. 美国绿卡基础知识:I-539和I-129表格的应用回复新帖
  7. 用python放烟花咯
  8. android录音声波动画,Android开发:仿微信 录音声波
  9. 使用CRF++实现命名实体识别
  10. jQuery学习之旅 Item1 选择器【一】