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 ...
随机推荐
- codeforces 566D D. Restructuring Company(并查集)
题目链接: D. Restructuring Company time limit per test 2 seconds memory limit per test 256 megabytes inp ...
- poj 2689Prime Distance(区间素数)埃氏筛法
这道题的L和R都很大,所以如果直接开一个1~R的数组明显会超时.但是R-L并不大,所以我们考虑把这个区间(L--R)移动到(1--(R-L+1))这个区间再开数组(就是把每个数减L再加1).接下来先用 ...
- ACM学习历程——HDU 5014 Number Sequence (贪心)(2014西安网赛)
Description There is a special number sequence which has n+1 integers. For each number in sequence, ...
- ACM学习历程——UVA127 "Accordian" Patience(栈, 链表)
Description ``Accordian'' Patience You are to simulate the playing of games of ``Accordian'' patie ...
- C#如何立即回收内存
1.把对象赋值为null 2.立即调用GC.Collect(); 注意:这个也只是强制垃圾回收器去回收,但具体什么时候执行不确定. 代码: class Test { ~Test() { Consol ...
- DSP编程
File:isctype.c Line 68 DSP/BIOS程序启动顺序 CCS V5 使用教程一: 安装激活与创建工程 CCS V5 使用教程二:创建工程和配置软件仿真 CCS V5 使用教程三: ...
- 【245】◀▶IEW-Unit10
Unit 10 Censorship 1. Model1题目及范文分析 Some parents believe that there is no harm in allowing their chi ...
- SynEdit(Delphi XE7)的安装和基本使用
一.花絮 delphi自带的memo显示sql语句看的太累人了,今天决定美化一下.最起码要有“语法着色”.“显示行号”这2个功能. 意外发现了 SynEdit 控件. SynEdit是一个免费的文字编 ...
- FZU2056 最大正方形(二分答案)
Problem 2056 最大正方形 Accept: 171 Submit: 516Time Limit: 1000 mSec Memory Limit : 32768 KB Probl ...
- 利用 druid 的 sql parser 模块解析 sql 语句
druid 是阿里开源在 github 上面的数据库连接池,里面有一个专门解析 sql 语句的模块 源码位置: https://github.com/alibaba/druid SQL Parse ...