Floodfill求连通分量
floodfill的基本思路就是找到所有连在一起的结点并染成相同的颜色,这样就可以通过颜色区分各个连通分量。具体来说,一开始把所有结点都设成相同的颜色,然后从第一个结点往后遍历,遇到还未被染成其他色的结点,表明这个结点不属于任何已知的连通分量,所以给它一个新颜色,并用bfs/dfs给与其相连的所有结点都染成这个颜色。
代码如下:
1 //邻接链表实现floodfill 2 class Graph { 3 private: 4 int n; 5 int *color; 6 vector<int> *edges; 7 8 public: 9 Graph(int input_n) { 10 n = input_n; 11 edges = new vector<int>[n]; 12 color = new int[n]; 13 //set all color to be the 0 at first 14 memset(color, 0, n * sizeof(int)); 15 } 16 17 ~Graph() { 18 delete[] edges; 19 delete[] color; 20 } 21 22 void insert(int x, int y) { 23 edges[x].push_back(y); 24 edges[y].push_back(x); 25 } 26 27 void floodfill() { 28 int color_cnt=0; 29 //bfs for every node as starting node 30 for(int i=0;i<n;i++){ 31 //if color==0 means it is seperate from previous ones 32 //so should start a new connected component 33 if(color[i]==0){ 34 //update color for this component 35 color_cnt++; 36 color[i]=color_cnt; 37 queue<int> q; 38 //this node will be the "root node" for this component 39 q.push(i); 40 while(!q.empty()){ 41 int vertex=q.front(); 42 for(int j: edges[vertex]){ 43 if(color[j]==0){ 44 color[j]=color_cnt; 45 q.push(j); 46 } 47 } 48 q.pop(); 49 } 50 } 51 } 52 for(int i=0;i<n;i++){ 53 cout<<i<<" "<<color[i]<<endl; 54 } 55 } 56 };
这里再给一个例子,大意就是找出上下左右相连通的连通块(‘*')的个数:
1 //floodfill求连通块个数 2 #include <iostream> 3 #include <cstring> 4 using namespace std; 5 6 int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; 7 char map[1001][1001]; 8 int color[1001][1001]; 9 int height,width; 10 11 void dfs(int x, int y, int cur_color){ 12 int curx, cury; 13 for(int i=0;i<4;i++){ 14 curx=x+dir[i][0]; 15 cury=y+dir[i][1]; 16 if(map[curx][cury]=='*'&&color[curx][cury]==0){ 17 color[curx][cury]=cur_color; 18 dfs(curx,cury,cur_color); 19 } 20 } 21 } 22 23 int floodfill(){ 24 int color_cnt=0; 25 for(int i=1;i<=height;i++){ 26 for(int j=1;j<=width;j++){ 27 if(map[i][j]=='*'&&color[i][j]==0){ 28 color_cnt++; 29 dfs(i,j,color_cnt); 30 } 31 } 32 } 33 return color_cnt; 34 } 35 36 37 int main(){ 38 cin>>height>>width; 39 for(int i=0;i<=height+1;i++){ 40 for(int j=0;j<=width+1;j++){ 41 map[i][j]='x'; 42 } 43 } 44 for(int i=1;i<=height;i++){ 45 for(int j=1;j<=width;j++){ 46 cin>>map[i][j]; 47 } 48 } 49 memset(color,0,sizeof(color)); 50 cout<<floodfill()<<endl; 51 }