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 ...
随机推荐
- next enum in swift
enum Iter: Int{ case s1=0, s2, s3, s4 mutating func next(){ if self == .s4 { self = .s1 return } sel ...
- Unity-2017.3官方实例教程Space-Shooter(一)
由于初学Unity,写下此文作为笔记,文中难免会有疏漏,不当之处还望指正. Unity-2017.3官方实例教程Space-Shooter(二) 章节列表: 一.从Asset Store中下载资源并导 ...
- MySQL当月负毛利订单明细_20161027
#当月每天负毛利订单明细 SELECT c.ID,a.city AS 城市,a.username AS 用户ID,a.订单日期,a.订单号,a.销售确认额,a.成本额,a.毛利1, CASE THEN ...
- JVM(一)虚拟机内存划分
Java内存区域 线程私有数据区域:虚拟机栈,本地方法栈,程序计数器 线程共享数据区域:方法区,堆 程序计数器:当前线程所执行的字节码的行号指示器,JVM通过这个字节码解释器改变计数器的值,以选择下一 ...
- SpringMVC 全注解实现 (1) servlet3.0以上的容器支持
一. Spring MVC入门 1.1 request的处理过程 用户每次点击浏览器界面的一个按钮,都发出一个web请求(request).一个web请求的工作就像一个快递员,负责将信息从一个地方运送 ...
- window下redis如何查看版本号
1.启动服务端:redis-server 2.启动客户端:redis-cli 3.客户端输入:info 即可.
- Newtonsoft.Json null值不序列化
如果对当前序列化的实体全部生效的话使用如下: var jSetting = new JsonSerializerSettings {NullValueHandling = NullValueHandl ...
- 模块 DLL C:\WINDOWS\system32\inetsrv\aspnetcore.dll 未能加载。返回的数据为错误信息。
更新了win10的版本后,就启动原来的iis发布的程序 程序池就自动关闭.后来 启动网站 iis程序池自动关闭. 在为应用程序池“.NET v4.5”提供服务的工作进程“21908”中,协议“http ...
- jsp九大内置对象与servlet中java对象
jsp九大内置对象 request对象 : getParameter(String name)获取表单提交的数据 getParamegerNames() 获取客户端提交的所有参数名 getAttri ...
- HDU - 6113 2017百度之星初赛A 度度熊的01世界
度度熊的01世界 Accepts: 967 Submissions: 3064 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 327 ...