您的位置:首页 > 其它

深度优先搜索练习之神奇的矩环

2017-08-07 17:48 288 查看
小鑫的女朋友被魔王抢走了!

魔王留给小鑫一张n*m大的表,上面有各种各样的颜色,用A-Z这26个字母来表示。魔王留给他一个任务,如果小鑫可以在这张表中找出任意一个长度大于1的环,并且这个环的颜色是相同的,魔王就把小鑫的女朋友还给他。为了从魔王手中夺回他的女朋友,小鑫请你帮忙,你能帮帮他吗?


Input

多组输入。

每组的第一行有两个整数n,m。代表表的大小。

接下来是由A-Z的一些字母所构成的n行m列的表。

1<=n,m<=200


Output

如果可以救回他的女朋友,输出Yes,否则输出No


Example Input

4 7
ABCBBAA
BCBCBCB
AABBCCA
ACCCBBB
10 3
AAC
ABB
BBA
AAC
CBC
CCA
CBB
CCA
CCB
BAA



Example Output

No
Yes

 三个小时折腾出这一道题。。。题意很明确,就是判断图中是否有环,如果当前点已被访问,它的下一个节点也被访问且不是当前点的父节点,那么就是有环,由于图中字母不一样,所以挨个遍历每个字母相同的连通块看是否有环

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;
const int N = 210;

int n, m;
char map

;
bool vis

;
bool flag;
int xx[4] = {1, 0, 0, -1};
int yy[4] = {0, 1, -1, 0};

void DFS(int x, int y, int xp, int yp)  //x,y为当前点的坐标,xp,yp为父节点
{
vis[x][y] = 1;
for(int k = 0; k < 4; k++)
{
int i = x + xx[k];
int j = y + yy[k];
if(i >= 0 && i < n && j >= 0 && j < m && map[i][j] == map[x][y])
{
if(!vis[i][j])
DFS(i, j, x, y);
else if(i != xp && j != yp)  //当前点的下一点不是父节点且已经被访问,说明有环
{
flag = true;
return;
}
}

}
}
int main()
{
while(~scanf("%d%d", &n, &m))
{
memset(vis, 0, sizeof(vis));
for(int i = 0; i < n; i++)
scanf("%s", map[i]);
flag = false;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if(!vis[i][j])
{
DFS(i, j, i, j);  //访问每个连通块
if(flag)
break;
}
}
if(flag)
break;
}
if(flag)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: