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 }

 

posted @ 2018-08-03 10:21  fishers  阅读(543)  评论(0)    收藏  举报