日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Codeforces Round #375 (Div. 2) D. Lakes in Berland 并查集

發布時間:2025/7/14 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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 = 70 * 70; char str[50 + 20][50 + 20]; int fa[maxn]; LL size[maxn]; int calc(int x, int y) {return 50 * 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 = 1; i <= n; ++i) {scanf("%s", str[i] + 1);}for (int i = 0; i <= maxn - 1; ++i) {size[i] = 1;fa[i] = i;}for (int i = 1; i <= n; ++i) {size[calc(i, 1)] = inf;size[calc(i, m)] = inf;}for (int i = 1; i <= m; ++i) {size[calc(1, i)] = inf;size[calc(n, i)] = inf;}for (int i = 1; i <= n; ++i) {for (int j = 1; j <= m; ++j) {if (str[i][j] == '.') {if (str[i - 1][j] == '.' && i - 1 >= 1) {merge(calc(i - 1, j), calc(i, j));}if (str[i][j - 1] == '.' && j - 1 >= 1) merge(calc(i, j), calc(i, j - 1));}}}for (int i = 1; i <= n; ++i) {for (int j = 1; 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] = 1;}}multiset<struct node> :: iterator it = ss.begin();int cut = ss.size() - k;int ans = 0;while (cut--) {del[it->FA] = 1;ans += size[it->FA];it++;}printf("%d\n", ans);for (int i = 1; i <= n; ++i) {for (int j = 1; j <= m; ++j) {int FA = find(calc(i, j));if (del[FA]) {printf("*");} else printf("%c", str[i][j]);}printf("\n");} }int main() { #ifdef localfreopen("data.txt","r",stdin); #endifwork();return 0; } View Code

?

轉載于:https://www.cnblogs.com/liuweimingcprogram/p/5933324.html

總結

以上是生活随笔為你收集整理的Codeforces Round #375 (Div. 2) D. Lakes in Berland 并查集的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。