Codeforces Round #375 (Div. 2) D. Lakes in Berland 并查集
http://codeforces.com/contest/723/problem/D
这题是只能把小河填了,题目那里有写,其实如果读懂题这题是挺简单的,预处理出每一块的大小,排好序,从小到大填就行了。
以前找这些块的个数用的是dfs。现在这次用并查集做下。
首先要解决的是,二维坐标怎么并查集,以前的并查集都是一维的,现在是两个参数,那么就考虑离散,每对应一个点,离散到一个独特的一维数值即可。我用的公式的50 * x + y。这样得到的数值是唯一的。所以可以快乐地并查集了。
那么遇到一个'.',我们需要它和其他合并,思路就是观察其上面和左边是否存在'.',如果存在,就合并到左边(上面),没有,那就是自己一个块了。
有顺序的,检查完上面,合并完(现在爸爸是上面那个),还要检查左边,如果有,左边的就要合并过来。这样爸爸就只是上面那个了。
为什么要这样做呢?因为考虑下这个
***.**
*. ..**
枚举到加粗那个的时候,如果你只向左合并,则遗漏了上面那个,向上合并,又会使得左边的被算作不同的块。GG
所以是需要两边判断,同时合并的。注意合并的方向是固定的,需要及时选择那个是爸爸
然后就是排序删除了,每个点的爸爸是固定的,用个标记数组标记下删除了那个爸爸,输出的时候对应一下 就好
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = * ;
char str[ + ][ + ];
int fa[maxn];
LL size[maxn];
int calc(int x, int y) {
return * x + y;
}
int find(int x) {
if (fa[x] == x) return x;
else return fa[x] = find(fa[x]);
}
void merge(int x, int y) {
x = find(x);
y = find(y);
if (x != y) {
fa[y] = x;
size[x] += size[y];
}
}
int del[maxn];
struct node {
LL size;
int FA;
bool operator < (const struct node &rhs) const {
return size < rhs.size;
}
node(LL aa, int bb) : size(aa), FA(bb) {}
};
multiset<struct node>ss;
bool used[maxn];
void work() {
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
for (int i = ; i <= n; ++i) {
scanf("%s", str[i] + );
}
for (int i = ; i <= maxn - ; ++i) {
size[i] = ;
fa[i] = i;
}
for (int i = ; i <= n; ++i) {
size[calc(i, )] = inf;
size[calc(i, m)] = inf;
}
for (int i = ; i <= m; ++i) {
size[calc(, i)] = inf;
size[calc(n, i)] = inf;
}
for (int i = ; i <= n; ++i) {
for (int j = ; j <= m; ++j) {
if (str[i][j] == '.') {
if (str[i - ][j] == '.' && i - >= ) {
merge(calc(i - , j), calc(i, j));
}
if (str[i][j - ] == '.' && j - >= ) merge(calc(i, j), calc(i, j - ));
}
}
}
for (int i = ; i <= n; ++i) {
for (int j = ; j <= m; ++j) {
if (str[i][j] == '*') continue;
int FA = find(calc(i, j));
if (used[FA]) continue;
if (size[FA] >= inf) continue;
ss.insert(node(size[FA], FA));
used[FA] = ;
}
}
multiset<struct node> :: iterator it = ss.begin();
int cut = ss.size() - k;
int ans = ;
while (cut--) {
del[it->FA] = ;
ans += size[it->FA];
it++;
}
printf("%d\n", ans);
for (int i = ; i <= n; ++i) {
for (int j = ; j <= m; ++j) {
int FA = find(calc(i, j));
if (del[FA]) {
printf("*");
} else printf("%c", str[i][j]);
}
printf("\n");
}
} int main() {
#ifdef local
freopen("data.txt","r",stdin);
#endif
work();
return ;
}
Codeforces Round #375 (Div. 2) D. Lakes in Berland 并查集的更多相关文章
- Codeforces Round #375 (Div. 2) D. Lakes in Berland 贪心
D. Lakes in Berland 题目连接: http://codeforces.com/contest/723/problem/D Description The map of Berland ...
- Codeforces Round #375 (Div. 2)——D. Lakes in Berland(DFS连通块)
D. Lakes in Berland time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- Codeforces Round #375 (Div. 2) D. Lakes in Berland dfs
D. Lakes in Berland time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- Codeforces Round #375 (Div. 2) D. Lakes in Berland (DFS或并查集)
D. Lakes in Berland time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- Codeforces Round #181 (Div. 2) B. Coach 带权并查集
B. Coach 题目连接: http://www.codeforces.com/contest/300/problem/A Description A programming coach has n ...
- Codeforces Round #345 (Div. 1) C. Table Compression dp+并查集
题目链接: http://codeforces.com/problemset/problem/650/C C. Table Compression time limit per test4 secon ...
- Codeforces Round #346 (Div. 2) F. Polycarp and Hay 并查集 bfs
F. Polycarp and Hay 题目连接: http://www.codeforces.com/contest/659/problem/F Description The farmer Pol ...
- Codeforces Round #363 (Div. 2) D. Fix a Tree —— 并查集
题目链接:http://codeforces.com/contest/699/problem/D D. Fix a Tree time limit per test 2 seconds memory ...
- Codeforces Round #603 (Div. 2) D. Secret Passwords(并查集)
链接: https://codeforces.com/contest/1263/problem/D 题意: One unknown hacker wants to get the admin's pa ...
随机推荐
- 机器视觉 Histogram of oriented gradients
Histogram of oriented gradients 简称 HoG, 是计算机视觉和图像处理领域一种非常重要的特征,被广泛地应用于物体检测,人脸检测,人脸表情检测等. HoG 最早是在200 ...
- Git Shell Warning
Warning: Permanently added 'github.com,192.30.252.120' <RSA> to the list of known hosts. The a ...
- BZOJ-3626:LCA(离线+树链剖分)
Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q ...
- ACM学习历程—POJ1151 Atlantis(扫描线 && 线段树)
Description There are several ancient Greek texts that contain descriptions of the fabled island Atl ...
- ACM学习历程——UVA442 Matrix Chain Multiplication(栈)
Description Matrix Chain Multiplication Matrix Chain Multiplication Suppose you have to evaluate ...
- 【LeetCode】047. Permutations II
题目: Given a collection of numbers that might contain duplicates, return all possible unique permutat ...
- 【算法模板】Binary Search 二分查找
模板:(通用模板,推荐) 给定一个排序的整数数组(升序)和一个要查找的整数target,用O(logn)的时间查找到target第一次出现的下标(从0开始),如果target不存在于数组中,返回-1. ...
- nginx 反向代理配置
转载一篇特别好的nginx配置博文:http://www.cnblogs.com/hunttown/p/5759959.html
- makefile 使用【转载】
该篇文章为转载,是对原作者系列文章的总汇加上标注. 支持原创,请移步陈浩大神博客: http://blog.csdn.net/haoel/article/details/2886 makefile很重 ...
- 【转】android adb常用指令
Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态. 可以通过下列几种方法加入adb: 在设备上运行shell命令 通过端口转发来管理模拟器或设备 从模拟器或 ...