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 并查集的更多相关文章

  1. 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 ...

  2. 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 ...

  3. 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 ...

  4. 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 ...

  5. Codeforces Round #181 (Div. 2) B. Coach 带权并查集

    B. Coach 题目连接: http://www.codeforces.com/contest/300/problem/A Description A programming coach has n ...

  6. Codeforces Round #345 (Div. 1) C. Table Compression dp+并查集

    题目链接: http://codeforces.com/problemset/problem/650/C C. Table Compression time limit per test4 secon ...

  7. 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 ...

  8. 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 ...

  9. 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 ...

随机推荐

  1. 【C】四则运算生成和核对器----by郁卓、谢明浩

    [Github项目地址] 完成功能: 1. 使用 -n 参数控制生成题目的个数 2. 使用 -r 参数控制题目中数值(自然数.真分数和真分数分母)的范围 3. 生成的题目中计算过程不能产生负数,也就是 ...

  2. LinkedList_1.打印两个有序链表的公共部分

    思路: 实例化出两个链表($link_a, $link_b),比较连个链表当前元素的大小,谁小谁执行next()方法继续比较,当出现相当的时候把相等的值塞入数组$common里,当两个链表有一个元素比 ...

  3. 在线接口管理工具-eoapi

    为了方便和前端沟通,临时在局域网搭建了一个接口管理工具,查了一些资料都说eoapi不错,那就试了一下: 1.安装 要在服务器或者自己的电脑,准备web环境,Linux可以是Apache/nginx , ...

  4. mysql数据库表分区详解(数量过大的数据库表通过分区提高查询速度)

    这篇文章主要介绍了MySQL的表分区,例如什么是表分区.为什么要对表进行分区.表分区的4种类型详解等,需要的朋友可以参考下 一.什么是表分区通俗地讲表分区是将一大表,根据条件分割成若干个小表.mysq ...

  5. 《Java多线程编程核心技术》读后感(十)

    一生产一消费:操作栈 本实例是使生产者向堆栈List对象中放入数据,使消费者从List堆栈中取出数据.List最大容量是1 package Third; import java.util.ArrayL ...

  6. centos6.5安装filezilla

    下载filezilla https://filezilla-project.org/download.php?show_all=1 tar jxf _FileZilla_3.9.0.1_x86_64- ...

  7. js如何判断当前文本的输入状态——中文输入法的那些坑

    相信各位在平时接需求的时候肯定会遇到这样的一些需求,例如,要求输入框限制输入长度,限制输入类型,限制只能英文输入,限制只能输入大写字母等等,这时候我们一般的思路无非两种,一种是弹出特定的键盘,第二种是 ...

  8. 权限验证MVC

    http://www.jb51.net/article/20147.htm  引用 <authentication mode="Forms"><!--权限受到阻碍 ...

  9. Swoole WebSocket 的应用

    目录 概述 代码 小结 概述 这是关于 Swoole 学习的第三篇文章:Swoole WebSocket 的应用. 第二篇:Swoole Task 的应用 第一篇:Swoole Timer 的应用 什 ...

  10. 【读后感1】SQL2008技术内幕- SQL逻辑查询处理

    引言观点 1. 编程语言日新月异,但是从没有人否定sql 在现代编程中的巨大作用和 持续的可利用性.SQL以对人类友好的阅读体验提供数据查询能力( 相比其他编程语言 ), 同时在各种数据库平台中,基础 ...