题目链接:点击打开链接
这道题我用的是并查集: 将题中图生成了一个无向图,标号为 i*m+j ( i, j 分别为行号, 列号, 下标均从 0 开始)
图中的 n*m 个点 编号分别为 : 0,1,2,3,... n*m-1 ;
如果 map[x1][y1] == map[x2][y2] , 且 (x1, y1) 和 (x2, y2) 相邻 , 那么 点x1*m+y1 和 点 x2*m+y2 之间存在一条无向边。
注 : 并查集可以判断图中是否有环。
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
const int N = 200010;
char map[55][55];
int road[4][2] = {-1,0, 1,0, 0,-1, 0,1};
int f[N];
int Find(int x)
{
return x==f[x]?x:f[x]=Find(f[x]);
}
typedef struct edge
{
int s, e;
} Edge;
Edge a[N];
int vis[55][55];
int main()
{
int n, m;
cin >> n >> m;
memset(vis, 0, sizeof(vis));
for(int i=0; i<n; i++)
{
cin >> map[i];
}
int cnt = 0;
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
int temx, temy;
for(int k=0; k<4; k++)
{
temx = i+road[k][0];
temy = j+road[k][1];
if(vis[temx][temy] || temx < 0 || temx > n || temy < 0 || temy > m)
continue;
if(map[temx][temy] == map[i][j])
{
int s = i*m+j, e = temx*m+temy;
a[++cnt].s = s;
a[cnt].e = e;
/* a[++cnt].e = s;
a[cnt].s = e;*/
}
}
vis[i][j] = 1;
}
}
int sroot, eroot;
bool flag = 0;
for(int i=0; i<=N-10; i++)
f[i] = i;
/* for(int i=1; i<=cnt; i++) {
cout << a[i].s << "-->" << a[i].e << endl;
}*/
for(int i=1; i<=cnt; i++)
{
sroot = Find(a[i].s);
eroot = Find(a[i].e);
if(sroot == eroot)
{
flag = 1;
break;
}
else
f[sroot] = eroot;
}
if(flag) cout << "Yes" << endl;
else cout << "No" << endl;
return 0;
}