Language: C++

#include <bits/stdc++.h>
using namespace std;

struct Point{
	int h,w;
	Point(){};
	Point(int h_,int w_){
		h=h_,w=w_;
	};
};

Point operator+(const Point& a,const Point& b){return Point(a.h+b.h,a.w+b.w);}

struct Board{

	int H,W;
	vector<string>s ;
	vector<Point>near;
	queue<Point> que;
	vector<vector<int>> dist;
	vector<vector<bool>> visited;
	int ans;

	Board(){};
	Board(int h_,int w_){
		H=h_,W=w_;
		s.resize(H);
		near={{-1,0},{1,0},{0,-1},{0,1}};
		init_dist();
		init_visited();
	};
	bool in_board0(int x,int y){if(0<=x && x<H && 0<=y && y<W)return true;else return false;} 
	bool in_board(Point p){if(0<=p.h && p.h<H && 0<=p.w && p.w<W)return true;else return false;} 
	char get_char(Point p){return s[p.h][p.w];}
	vector<Point> get_near(Point p){vector<Point>ret;for(auto&& u:near)ret.emplace_back(p+u);return ret;}

	int  get_dist(Point p){return dist[p.h][p.w];}
	int  set_dist(Point p,int i){dist[p.h][p.w]=i;}
	void init_dist(){dist.assign(H,vector<int>(W,-1));}

	int  is_visited(Point p){return visited[p.h][p.w];}
	int  set_visited(Point p,bool i){visited[p.h][p.w]=i;}
	void init_visited(){visited.assign(H,vector<bool>(W,false));}


	void dfs(Point p){
		if(is_visited(p))return;
		set_visited(p,true);
		char c1,c2;
		c1=get_char(p);
		for(auto&& q:near){
			Point u=p+q;
		
		if(! in_bound(u))continue;
		c2=get_char(u);	
	    if(!is_visited(u) && c1!=c2){
				 
				if(c2=='.'){ans++;}//cout<<"w "<<u.h<<" "<<u.w<<endl;}
				dfs(u);
		}
		}
	}

	void dfs0(int x,int y){
		if(visited[x][y])return;
		visited[x][y]=true;
		char c1=s[x][y];
		for(auto&& q:near){
			int x0=x+q.h,y0=y+q.w;
		if(!in_board0(x0,y0))continue;
		char c2=s[x0][y0];
		if( !ivisited[x0][y0] && c1!=c2){
				 
				if(c2=='.'){ans++;}//cout<<"w "<<u.h<<" "<<u.w<<endl;}
				dfs0(x0,y0);
		}
		}
	}

	int do_all_dfs(){
		ans=0;
		for (int i;i<H;i++)for(int j=0;j<W;j++){
		
		if(s[i][j]=='#'){
	//		cout<<"b "<<p.h<<" "<<p.w<<endl;
		init_visited();
		dfs(i,j);
		}}
		return ans;
	}

	void bfs(){
		while(! que.empty()){
		Point p=que.front();que.pop();	
		for(auto&& u:get_near(p)){
		if(in_board(u) && ! is_visited(u) && get_char(p)!=get_char(u)){
			set_visited(u,true);
			if(get_char(u)=='.')ans++;
			que.push(u);
		}}
		}}

	int do_all_bfs(){for (int i;i<H;i++)for(int j=0;j<W;j++){
		ans=0;
		for (int i;i<H;i++)for(int j=0;j<W;j++){
		Point p(i,j);
		if(get_char(p)=='#'){
	//		cout<<"b "<<p.h<<" "<<p.w<<endl;
		init_visited();
		que.push(p);
		set_visited(p,true);
		bfs();
		}}
		return ans;
	}
	}

};


int main(){
	int h,w;cin>>h>>w;
	Board bd(h,w);
	for(auto&& u:bd.s)cin>>u;
//	for(auto&& u:bd.s)cout<<u<<endl;
	cout<<bd.do_all_dfs()<<endl;
}


Compiler output:
a.cc: In member function 'int Board::set_dist(Point, int)':
a.cc:38:55: warning: no return statement in function returning non-void [-Wreturn-type]
   38 |         int  set_dist(Point p,int i){dist[p.h][p.w]=i;}
      |                                                       ^
a.cc: In member function 'int Board::set_visited(Point, bool)':
a.cc:42:62: warning: no return statement in function returning non-void [-Wreturn-type]
   42 |         int  set_visited(Point p,bool i){visited[p.h][p.w]=i;}
      |                                                              ^
a.cc: In member function 'void Board::dfs(Point)':
a.cc:54:22: error: 'in_bound' was not declared in this scope; did you mean 'in_board'?
   54 |                 if(! in_bound(u))continue;
      |                      ^~~~~~~~
      |                      in_board
a.cc: In member function 'void Board::dfs0(int, int)':
a.cc:72:22: error: 'ivisited' was not declared in this scope; did you mean 'visited'?
   72 |                 if( !ivisited[x0][y0] && c1!=c2){
      |                      ^~~~~~~~
      |                      visited
a.cc: In member function 'int Board::do_all_dfs()':
a.cc:87:20: error: no matching function for call to 'Board::dfs(int&, int&)'
   87 |                 dfs(i,j);
      |                 ~~~^~~~~
a.cc:46:14: note: candidate: 'void Board::dfs(Point)'
   46 |         void dfs(Point p){
      |              ^~~
a.cc:46:14: note:   candidate expects 1 argument, 2 provided