前言
图(Graph)描述的是一些个体之间的关系。与线性表和二叉树不同的是:这些个体之间既不是前驱后继的顺序关系,也不是祖先后代的层次关系,而是错综复杂的网状关系。
例题6-12 油田(Oil Deposits,UVa 572)
题意:
输入一个m行n列的字符矩阵,统计字符“@”组成多少个八连块。如果两个字符“@”所在的格子相邻(横、竖或者对角线方向),就说它们属于同一个八连块。
Sample Input
1 1
*
3 5
*@*@*
**@**
*@*@*
1 8
@@****@*
5 5
****@
*@@*@
*@**@
@@@*@
@@**@
0 0
Sample Output
0
1
2
2
-代码如下
#include <cstdio>
#include <cstring>
const int maxn = 100 + 5;
char pic[maxn][maxn];
int m, n , idx[maxn][maxn];
void dfs(int r, int c, int id) {
if (r < 0 || r >=m || c >=n) return ; //“出界”的格子
if (idx[r][c] > 0 || pic[r][c] != '@') return ; //不是"@"或者已经访问过的格子
idx[r][c] = id; //连通分量编号
for (int dr = -1; dr <= 1; dr++)
for (int dc = -1; dc <= 1; dc++)
if (dr != 0 || dc != 0) dfs(r+dr, c+dc, id);
}
int main() {
while (scanf("%d%d",&m,&n) == 2 && m && n) {
for(int i = 0; i < m; i++) scanf("%s",pic[i]);
memset(idx, 0, sizeof(idx));
int cnt = 0;
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
if(idx[i][j] == 0 && pic[i][j] == '@') dfs(i, j, ++cnt);
printf("%d\n",cnt);
}
return 0;
}
图也有DFS遍历和BFS遍历,其中前者用递归实现,后者用队列实现。求多维数组连通块的过程也成为种子填充(floodfill)。