2025 : 简单环路(并查集)
生活随笔
收集整理的這篇文章主要介紹了
2025 : 简单环路(并查集)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
404
題目描述
有一個N x M 大小的地圖,地圖中的每個單元包含一個大寫字母。
若兩個相鄰的(這里的相鄰指“上下左右”相鄰)點上的字母相同,我們可以用線段連接這兩個點。
若存在一個包含同一字母的環路,那么連接這些點我們可以得到一個多邊形,
當且僅當多邊形的邊數大于等于4時,我們稱這幅地圖中存在“簡單環路”。
現在給你一份地圖,你來判斷是否存在“簡單環路”。
列如:
3 4
AAAA
ABCA
AAAA
字符“A”可以構成一個“簡單環路”,其邊數為4。
輸入
第一行輸入兩個正整數n,m,2<=n,m<=50,分別表示地圖的行列數。
接下來輸入n行,每行m個大寫字母。
輸出
若存在“簡單環路”輸出“Yes”,否則輸出“No”。
樣例輸入
3 4
AAAA
ABCA
AADA
樣例輸出
No
思路
并查集,把每個相同的點合成一個祖先。如果遇到兩個點相同,而且他們的祖先也相同,那么就形成環了。
AC
#include<bits/stdc++.h> #define ll long long #define mem(a, b) memset(a, b, sizeof(a)) #define N 105 using namespace std; char g[N][N]; int n, m; int pre[N * N]; // 獲取每個坐標的唯一id int id(int i, int j) {return i * m + j; } //祖先初始化 void init() {for (int i = 0; i < N * N; i++) {pre[i] = i;} } // 查找祖先 int find (int x) {if (x == pre[x]) return x;else return pre[x] = find(pre[x]); } int main() { // freopen("in.txt", "r", stdin);while (scanf("%d%d", &n, &m) != EOF) {for (int i = 0; i < n; i++) {scanf("%s", &g[i]);}init();int flag = 0;for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {//左右方向 if (g[i][j] == g[i][j + 1]) {int u = id(i, j);int v = id(i, j + 1);int find_u = find(u);int find_v = find(v);if (find_u != find_v) {pre[find_u] = pre[find_v];find(find_u);}else {flag = 1;break;}}//上下方向 if (g[i][j] == g[i + 1][j]) {int u = id(i, j);int v = id(i + 1, j);int find_u = find(u);int find_v = find(v); if (find_u != find_v) {pre[find_u] = pre[find_v];find(find_u);}else {flag = 1;break;}}}if (flag) break;}if (flag) printf("Yes\n");else printf("No\n");}return 0; }總結
以上是生活随笔為你收集整理的2025 : 简单环路(并查集)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2049 : 压死骆驼的最后一根稻草 (
- 下一篇: pair的使用