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,这个也好奇怪呀... # ...
随机推荐
- AppleScript
一.资源 1.书本 2.ide: AppleSreipt Editor 3.界面辅助软件: UIBrowser 破解方法: a) ui browser -> show package conte ...
- mysql import data slow solution---overview information
1 SELECT SUM(DATA_LENGTH)+SUM(INDEX_LENGTH) FROM information_schema.tables WHERE TABLE_SCHEMA='dat ...
- AGS API for JavaScript 图表上地图
原文:AGS API for JavaScript 图表上地图 图1 图2 图3 -------------------------------------华丽丽的分割线--------------- ...
- 折腾Centos6.4记
背景: 闲置了一台Thinkpad,之前装的是Kali Linux,但无线网卡挂掉了,加之硬盘分区不当,平时几乎没怎么用,重新使用kali的livecd进行分区,然后安装,总是出错,尝试了七八次,仍然 ...
- SqlServer2008R2执行Sql语句,快捷键
SqlServer2008R2执行Sql语句,快捷键Alt+X
- TestNG学习-002-annotaton 注解概述及其执行顺序
此文主要讲述用 TestNG 基础的 annotation (注解)知识,及其执行的顺序,并通过一个 TestNG 简单的实例演示 annotation 的执行顺序. 希望能对初学 TestNG 测试 ...
- sell-- wordPOI
1. http://poi.apache.org/ 2.创建项目,结构如下 三: 查看效果 打开: 测试源码: /* ========================================= ...
- ios项目生成ipa文件方法
做这些的前提是你配置好了所有的证书,如果还没先去配置证书吧. 1.打开需要生成ipa的ios项目.2.在运行按钮的后面选择ios Device3.点击Product 按钮,选择第五个Archive4. ...
- search搜索功能
1.html <div class="search"> <form name="formsearch" action=" ...
- iOS:crash崩溃日志分析
一.前言: 作为一个合格的iOS开发者,除了具有规范强悍的编码能力外,还应该具有过硬的查错纠错能力.在项目运行时,程序崩溃是不可避免的,遇到这个问题,有时会出现一大堆的crash日志,艹,貌似看不懂呀 ...