1.思路:
把二维矩阵转化成一维编号,之后将编号使用并查集,看最后是否在同一个集合中即可。
2.代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
int n, m, cnt, root;
int fa[N * N];
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
char mp[N][N];
void init(int x)
{
for (int i = 1; i <= x; i++)
{
fa[i] = i;
}
}
int find(int x)
{ // 查找,带路径压缩
return x == fa[x] ? x : (fa[x] = find(fa[x]));
}
void merge(int i, int j)
{
int x = find(i);
int y = find(j);
if (x != y)
{
fa[x] = y;
}
}
int convert(int x, int y)
{ // 将二维矩阵转化成一维编号
return (x - 1) * m + y;
}
int main()
{
cin >> n >> m;
init(n * m);
for (int i = 1; i <= n; i++)
{
cin >> (mp[i] + 1);
}
for (int i = 1; i <= m; i++)
{ // 判断下面至少有两层积木
if (mp[n][i] == '1')
{
cnt++;
}
}
if (cnt < 2)
{
cout << "No";
return 0;
}
// solve
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (mp[i][j] == '0')
{
continue;
}
if (!root)
{
root = convert(i, j);
}
for (int k = 0; k < 4; k++)
{
int x = i + dx[k];
int y = j + dy[k];
if (x < 1 || x > n || y < 1 || y > m)
{
continue;
}
if (mp[x][y] == '1')
{
merge(convert(i, j), convert(x, y));
}
}
}
}
// 判断是否全部联通
root = find(root);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (mp[i][j] == '1')
{
if (find(convert(i, j)) != root)
{
cout << "No";
return 0;
}
}
}
}
cout << "Yes";
return 0;
}