注意使用DFS求连通块因为递归调用函数,只能用于不大的数据,数据过大会递归爆栈!
1.输入一个N*M的字符矩阵,统计其中‘@’共组成多少个连通块(N与M不超过100)
#include<iostream>
#include<cstring>
using namespace std;
int n, m, vis[101][101]; //vis数组记录该点所在连通块的序号,不在则为零
char map[101][101];
int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 };
int num = 0;
void dfs(int x, int y,int num)
{
if (x >=n || x<0 || y>=m || y < 0||vis[x][y]>0||map[x][y]!='@') return;
vis[x][y] = num; //给该连通块标记序号
for (int i = 0; i < 4; i++) //四个方向DFS递归
dfs(x + dx[i], y + dy[i], num);
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> map[i][j];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
if (map[i][j] == '@'&&vis[i][j] == 0)
{
num++;
dfs(i, j, num);
}
}
cout << num << endl;
return 0;
}
2.输入一个N*M的字符矩阵,输入一个坐标,若该坐标在连通块中则输出该连通块有多少格(N与M不超过100)
#include<iostream>
#include<cstring>
using namespace std;
int n, m, vis[101][101];
char map[101][101];
int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 };
int num = 0, res[10001], sum = 1; //增加res数组每块连通块的个数
void dfs(int x, int y,int num)
{
if (x >n || x<1 || y>m || y < 1||vis[x][y]>0||map[x][y]!='@') return;
vis[x][y] = num;
sum++; //计数器自增统计个数
for (int i = 0; i < 4; i++)
dfs(x + dx[i], y + dy[i], num);
}
int main()
{
cin >> n >> m;
for (int i = 1; i <=n; i++)
for (int j = 1; j <= m; j++)
cin >> map[i][j];
for (int i = 1; i <=n; i++)
{
for (int j = 1; j <=m; j++)
if (map[i][j] == '@'&&vis[i][j] == 0)
{
sum = 0;
num++;
dfs(i, j, num);
res[num] = sum;
}
}
int p1, p2;
cin >> p1 >> p2;
if (vis[p1][p2] != 0)
cout << res[vis[p1][p2]] << endl;
else
cout << "该点不在连通块中!" << endl;
return 0;}
典型例题:颜色填涂
由数字 00 组成的方阵中,有一任意形状闭合圈,闭合圈由数字 11 构成,围圈时只走上下左右 44 个方向。现要求把闭合圈内的所有空间都填写成 22 .例如: 6 \times 66×6 的方阵( n=6n=6 ),涂色前和涂色后的方阵如下:
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 2 2 1
1 1 1 1 1 1
输入格式:
每组测试数据第一行一个整数
n(1 \le n \le 30)n(1≤n≤30)
接下来 nn 行,由 00 和 11 组成的 n \times nn×n 的方阵。
方阵内只有一个闭合圈,圈内至少有一个 00 。
#include<iostream>
using namespace std;
int n, map[31][31];
int vis[31][31];
int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 };
void dfs(int x, int y)
{
if (x > n || x<1 || y>n || y < 1 || vis[x][y]>0 || map[x][y] != 0) return;
vis[x][y] = 1;
for (int i = 0; i < 4; i++)
{
dfs(x + dx[i], y + dy[i]);
}
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> map[i][j];
if (map[i][j] == 1)
vis[i][j] = 2;
}
}
for (int i = 1, j = 1; j <= n; j++)
if (vis[i][j] == 0 && map[i][j] == 0)
dfs(i, j);
for (int i = n, j = 1; j <= n; j++)
if (vis[i][j] == 0 && map[i][j] == 0)
dfs(i, j);
for (int j = 1, i = 1; i <= n;i++)
if (vis[i][j] == 0 && map[i][j] == 0)
dfs(i, j);
for (int j = n, i = 1; i <= n; i++)
if (vis[i][j] == 0 && map[i][j] == 0)
dfs(i, j);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (vis[i][j] == 1)
cout << '0'<<' ';
if (vis[i][j] == 2)
cout << '1'<<' ';
if (vis[i][j] == 0)
cout << '2'<<' ';
}
cout << endl;
}
return 0;
}