DFS找连通分量问题,染色问题
DFS在2D网格上找连通分量问题
找连通分量的数量
求各连通分量的大小
...
题目①:蓝桥杯2018年省赛
题目②:POJ-1164-城堡问题
一、蓝桥杯2018年省赛
全球变暖
题目大意是有一张NxN像素的照片,图片中”#”代表陆地,”.”代表海洋。”上下左
右”4连通连成一片的陆地组成一座岛屿。
由于全球变暖,海平面上升,预计岛屿边缘一个像素范围内的陆地都会被淹
没。所谓岛屿边缘像素就是与海洋相邻的像素,也就是上下左右有海洋的像素。
思路:
用DFS找出来所有#号组成的连通分量。
同时计算每一个连通分量包含几个#号,以及包含几个与.点相邻的#号。
代码:
1 #include<iostream>
2 #include<string>
3 using namespace std;
4
5 /*
6 找连通分量
7
8 s存储地图 floor统计被淹没土地的数量 cnt统计原来陆地的数量
9 m表示岛屿(连通分量的个数)
10 dr方向数组
11
12
13 找连通分量:dfs m 双重循环枚举比较cnt与floor
14 dfs过程:标记走过 陆地数++ 四个方向搜索——周围有水域则会被淹——没水且没标记走过搜索下一个
15 dfs结束:直到把该岛屿搜索完结束dfs 此时已经标记完属于该岛屿的陆地
16 */
17
18 int ans=0,m=0,n,mark[1001][1001];
19 string s[1001];
20 int flood[100001],cnt[100001];
21 int dr[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
22
23 void dfs(int x,int y,int m){
24 mark[x][y] = 1;
25 cnt[m]++;
26 bool flooded = false;
27 for(int d=0;d<4;d++){
28 int nx = dr[d][0];
29 int ny = dr[d][1];
30 if( s[nx][ny]=='#' && mark[nx][ny]==0){
31 dfs(nx,ny,m);
32 }
33 if( s[nx][ny]=='.'){
34 flooded = true;
35 }
36 }
37 if(flooded) flood[m]++;
38 }
39
40 int main(){
41 cin>>n;
42 for(int i=0;i<n;i++){
43 cin>>s[i];
44 }
45 for(int i=0;i<n;i++){
46 for(int j=0;j<n;j++){
47 mark[i][j] = 0;
48 }
49 }
50
51 m=0,ans=0;
52 for(int i=0;i<n;i++){
53 for(int j=0;j<n;j++){
54 if(s[i][j] == '#' && !mark[i][j]){
55 m++;
56 cnt[m] = flood[m] = 0;
57 dfs(i,j,m);
58 if(flood[m] == cnt[m]) ans++;
59 }
60 }
61 }
62 cout<<ans<<endl;
63 return 0;
64 }
二、POJ 1164 城堡问题
连通分量,dfs染色
1 #include <iostream>
2 #include <cstring>
3 using namespace std;
4
5 /*
6 找连通分量个数 连通分量最大范围
7 dfs染色
8 */
9
10 int R,C; // 行列数
11 int rooms[60][60];
12 int color[60][60]; // 方块是否染色过的标记
13 int maxRoomArea = 0, roomNum = 0;
14 int roomArea;
15 void Dfs(int i,int k) {
16 if( color[i][k] )
17 return;
18
19 ++ roomArea;
20 color [i][k] = roomNum;
21 if( (rooms[i][k] & 1) == 0 ) Dfs(i,k-1); // 向西走
22 if( (rooms[i][k] & 2) == 0 ) Dfs(i-1,k); // 向北
23 if( (rooms[i][k] & 4) == 0 ) Dfs(i,k+1); // 向东
24 if( (rooms[i][k] & 8) == 0 ) Dfs(i+1,k); // 向南
25 }
26
27 int main() {
28 cin >> R >> C;
29 for( int i = 1;i <= R;++i)
30 for ( int k = 1;k <= C; ++k)
31 cin >> rooms[i][k];
32 memset(color,0,sizeof(color));
33 for( int i = 1;i <= R; ++i)
34 for( int k = 1; k <= C; ++ k) {
35 if( !color[i][k] ) {
36 ++ roomNum ;
37 roomArea = 0;
38 Dfs(i,k);
39 maxRoomArea = max(roomArea,maxRoomArea);
40 }
41 }
42 cout << roomNum << endl;
43 cout << maxRoomArea << endl;
44 return 0;
45 }

浙公网安备 33010602011771号