您的位置:首页 > 其它

1416 两点 并查集

2017-02-09 14:45 190 查看
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1416

对于每一个坐标(x, y)

要使得它变成一个整数,一个方法就是x * max(n, m) + y

这样就不会相同了。可以幻想一下吧。

这样坐标的大小只会去到n * m + y这个级别,不会很大。

然后并查集那里,每一次都走下面和右边的点,看看能否合并,能的话就合并。然后

合并到相同的爸爸,就是有了。

AA

AA

其中(4, 4)这个点被(1, 2)合并了一次,爸爸是(1, 1)

然后又被(2, 1)合并一次,爸爸是相同了。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
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>
#include <bitset>
const int maxn = 50 + 20;
int fa[maxn * maxn * maxn];
char str[maxn][maxn];
int tofind(int u) {
if (fa[u] == u) return fa[u];
else return fa[u] = tofind(fa[u]);
}
bool tomerge(int x, int y) {
x = tofind(x);
y = tofind(y);
if (x == y) return false;
fa[y] = x;
return true;
}
int n, m;
int calc(int x, int y) {
return max(n, m) * x + y;
}
void work() {
cin >> n >> m;
for (int i = 1; i <= n; ++i) cin >> str[i] + 1;
for (int i = 1; i <= maxn * maxn * maxn - 1; ++i) fa[i] = i;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (j + 1 <= m && str[i][j] == str[i][j + 1]) {
if (!tomerge(calc(i, j), calc(i, j + 1))) {
//                    cout << i << endl;
//                    cout << j << endl;
cout << "YES" << endl;
return;
}
}
if (i + 1 <= n && str[i][j] == str[i + 1][j]) {
if (!tomerge(calc(i, j), calc(i + 1, j))) {
cout << "YES" << endl;
return;
}
}
}
}
cout << "NO" << endl;
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
work();
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: