HDU 3688 Searchlights(并查集)

Each searchlight has a maximum level. You can decrease a searchlight’s level to save the energy. A searchlight whose maximum level is k can be turned to level k, k-1, k-2, …, 1 and 0. Level 0 means turning off the searchlight.
A grid is well-guarded if and only if at least one of the following two conditions is satisfied:
1.There is a searchlight in this grid, and it is not switched to level 0 (the light is on).
2.The grid is lightened by at least two searchlights. One lightens it in horizontal direction (east or west), and another lightens it in vertical direction (north or south).
Chandler asks you to help finding a solution that he can turn on some of the searchlights so that:
1.All the grids are well-guarded.
2.All the searchlights turned on are in a same level.
3.That same level mentioned above is as small as possible.
More specifically, if you choose a same level Q, then all the searchlights whose maximum level are less than Q have to be turned off. Please help him to find a solution with the minimum same level.
For each test case, the first line is two integers n and m, representing a grids land of size n×m. (0<n<=100, 0<m<=10000). Following n lines describe an n×m matrix in which ai,j means the maximum level of the searchlight in grid (i, j). ai,j can be zero, which means there is no searchlight on that grid. For all the cases, ai, j<=10000.
The input file ends with a line containing two zeros.
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef long long LL; const int MAXN = ;
const int MAXM = ; struct Node {
int a, x, y;
bool operator < (const Node &rhs) const {
if(a != rhs.a) return a < rhs.a;
if(x != rhs.x) return x < rhs.x;
return y < rhs.y;
}
} p[MAXN * MAXM]; int mat[MAXN][MAXM];
int xfa[MAXM][MAXN], yfa[MAXN][MAXM];
int xsize[MAXM][MAXN], ysize[MAXN][MAXM];
int n, m, s; void init() {
for(int j = ; j <= m; ++j)
for(int i = ; i <= n; ++i) xfa[j][i] = i, xsize[j][i] = ;
for(int i = ; i <= n; ++i)
for(int j = ; j <= m; ++j) yfa[i][j] = j, ysize[i][j] = ;
} int find_set(int *fa, int x) {
return fa[x] == x ? x : fa[x] = find_set(fa, fa[x]);
} void merge(int *fa, int *size, int x, int y) {
int fx = find_set(fa, x), fy = find_set(fa, y);
if(size[fx] < size[fy]) swap(fx, fy);
size[fx] += size[fy];
fa[fy] = fx;
} int solve() {
int largest = ;
for(int k = , i = ; i < s; ++k) {
if(k - >= largest) return k;
while(i < s && p[i].a == k) {
int x = p[i].x, y = p[i].y;
if(x - >= && mat[x - ][y] <= k) merge(xfa[y], xsize[y], x - , x);
if(x + <= n && mat[x + ][y] < k) merge(xfa[y], xsize[y], x, x + );
if(y - >= && mat[x][y - ] <= k) merge(yfa[x], ysize[x], y - , y);
if(y + <= m && mat[x][y + ] < k) merge(yfa[x], ysize[x], y, y + ); int fx = find_set(xfa[y], x), fy = find_set(yfa[x], y);
if(xsize[y][fx] == n || ysize[x][fy] == m) return -; if(find_set(xfa[y], ) == fx || find_set(xfa[y], n) == fx)
largest = max(largest, xsize[y][fx]);
else largest = max(largest, (xsize[y][fx] + ) / );
if(find_set(yfa[x], ) == fy || find_set(yfa[x], m) == fy)
largest = max(largest, ysize[x][fy]);
else largest = max(largest, (ysize[x][fy] + ) / ); ++i;
}
}
return -;
} int main() {
while(scanf("%d%d", &n, &m) != EOF) {
if(n == && m == ) break;
s = ;
for(int i = ; i <= n; ++i) {
for(int j = ; j <= m; ++j) {
scanf("%d", &mat[i][j]);
p[s].x = i;
p[s].y = j;
p[s++].a = mat[i][j];
}
}
sort(p, p + s);
init();
int ans = solve();
if(ans == -) puts("NO ANSWER!");
else printf("%d\n", ans);
}
}
HDU 3688 Searchlights(并查集)的更多相关文章
- HDU 2818 (矢量并查集)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2818 题目大意:每次指定一块砖头,移动砖头所在堆到另一堆.查询指定砖头下面有几块砖头. 解题思路: ...
- hdu 1116 欧拉回路+并查集
http://acm.hdu.edu.cn/showproblem.php?pid=1116 给你一些英文单词,判断所有单词能不能连成一串,类似成语接龙的意思.但是如果有多个重复的单词时,也必须满足这 ...
- Bipartite Graph hdu 5313 bitset 并查集 二分图
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5313 题意: 给出n个顶点,m条边,问最多添加多少条边使之构成一个完全二分图 存储结构: bitset ...
- hdu 3081(二分+并查集+最大流||二分图匹配)
Marriage Match II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- 2015 ACM/ICPC Asia Regional Changchun Online HDU - 5441 (离线+并查集)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5441 题意:给你n,m,k,代表n个城市,m条边,k次查询,每次查询输入一个x,然后让你一个城市对(u,v ...
- hdu 3536【并查集】
hdu 3536 题意: 有N个珠子,第i个珠子初始放在第i个城市.有两种操作: T A B:把A珠子所在城市的所有珠子放到B城市. Q A:输出A珠子所在城市编号,该城市有多少个珠子,该珠子转移了 ...
- HDU 1829 分组并查集
题意:有两种性别,每组数据表示是男女朋友,判断输入的几组数据是否有同性恋 思路:http://blog.csdn.net/iaccepted/article/details/24304087 分组并查 ...
- HDU 1198(并查集)
题意:给你11个图,每一个都有管道,然后给一张由这11个正方形中的n个组成的图,判断有几条连通的管道: 思路:在大一暑假的时候做过这道题,当时是当暴力来做的,正解是并查集,需要进行一下转换: 转换1: ...
- HDU 4496 D-City(并查集,逆思维)
题目 熟能生巧...常做这类题,就不会忘记他的思路了... //可以反过来用并查集,还是逐个加边,但是反过来输出...我是白痴.....又没想到 //G++能过,C++却wa,这个也好奇怪呀... # ...
随机推荐
- EFI
有CSM的UEFI BIOS应该可以支持EFI Native和legacy两种启动方式吧,在BIOS SETUP选项里面有的选. EFI在开机时的作用和BIOS一样,就是初始化PC,但在细节上却又不一 ...
- SQL Server批量数据导出导入Bulk Insert使用
简介 Bulk insert命令区别于BCP命令之处在于它是SQL server脚本语句,它可以将本地或远程的文件数据批量导入数据库,速度非常之快:远程文件必须共享才行, 文件路径须使用通用约定(UN ...
- Maximal Square || LeetCode
dp. #define MAX 1000 int rowLeft[MAX][MAX]; int colUp[MAX][MAX]; int dp[MAX][MAX]; void calRow(char ...
- linux pipe
1. 函数说明 pipe(建立管道): 1) 头文件 #include<unistd.h> 2) 定义函数: int pipe(int filedes[2]); 3) 函数说明: pipe ...
- thinkPHP 接支付宝及时到账接口
支付宝及时到帐接口,现在整理以下: 1.先将支付宝提供的公共类库函数库文件防盗thinkPHP的Vender目录下建的一个alipay文件下,以便之后的调用. //四个文件我分别给他们改了下名字,因为 ...
- django 部署到 apache
安装完django之后,每次都需要通过命令来启动启动开发服务器.虽然调试和测试方便,但只能在本地运行,并且不能承受许多用户同时使用的负载.所以需要将Django部署到生产级的服务器,这里选择apach ...
- windows安装java环境
1.下载安装jdk:以jdk-8u66-windows-x64为例. 2.JDK的环境变量配置 用鼠标右击“计算机”,选择“属性”->“高级系统设置”->“环境变量”->“系统变量” ...
- OceanBase架构浅析(二)
单点性能 OceanBase架构的优势在于既支持跨行跨表事务,又支持存储服务器线性扩展.当然,这个架构也有一个明显的缺陷:UpdateServer单点,这个问题限制了OceanBase集群的整体读写性 ...
- 实践JAVA wait(), notify(),sleep方法--一道多线程的面试题
建立三个线程,A线程打印10次A,B线程打印10次B,C线程打印10次C,要求线程同时运行,交替打印10次ABC. 这个问题用Object的wait(),notify()就可以很方便的解决. publ ...
- Android 利用ListView制作带竖线的多彩表格
1.listview与GridView 其实Android本身是有表格控件(GridView)的,但是GridView的每一列的宽度被限定为一样宽,有时设计表格时,列宽不可能为同一宽度,所有可以用Li ...