广搜——连通块
Wikioi 3410 别墅房间
题目描述 Description
小浣熊松松到他的朋友家别墅去玩,发现他朋友的家非常大,而且布局很奇怪。具体来说,朋友家的别墅可以被看做一个N*M的矩形,有墙壁的地方被标记为’#’,其他地方被标记为’.’。两个格子(a,b)和(c,d)被当做在同一个房间内,当且仅当|a-c|+|b-d|=1。现在松松想知道,有多少个房间。
输入描述 Input Description
第一行包含两个整数,N和M。
接下来N行描述别墅的情况,只包含’*’和’.’。
输出描述 Output Description
输出仅一行,为房间数。
样例输入 Sample Input
3 3
.#.
#.#
.#.
样例输出 Sample Output
5
数据范围及提示 Data Size & Hint
对于90%的数据,1<=N,M<=1000;
对于100%的数据,1<=N,M<=2000。
思路:
bfs求连通块
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<string> 5 6 using namespace std; 7 const int maxn = 2005; 8 int j[maxn][maxn],room[maxn][maxn]; 9 long long int total = 0,m,n; 10 struct pos{ 11 int x; 12 int y; 13 }; 14 pos q[4000000]; 15 pos dir[4]; 16 17 18 int bfs(int y,int x){ 19 int h = 0,t = 0; 20 q[0].y = y; 21 q[0].x = x; 22 int tx,ty; 23 while(h <= t){ 24 25 int r3 = 0; 26 for(r3 = 0;r3 < 4;r3++){ 27 x = q[h].x; 28 y = q[h].y; 29 tx = dir[r3].x; 30 ty = dir[r3].y; 31 if(y + ty >= 0 && y + ty < n && x + tx >= 0 && x + tx < m && room[y + ty][x + tx] && j[y + ty][x + tx]){ 32 t++; 33 q[t].y = y + ty; 34 q[t].x = x + tx; 35 j[y + ty][x + tx] = 0; 36 total--; 37 } 38 } 39 h++ ; 40 } 41 } 42 43 int main(){ 44 cin>>n>>m; 45 dir[0].x = -1;dir[0].y = 0; 46 dir[1].x = +1;dir[1].y = 0; 47 dir[2].x = 0;dir[2].y = -1; 48 dir[3].x = 0;dir[3].y = +1; 49 char cmd; 50 int r1 = 0,r2 = 0,temp = -1; 51 for(r1 = 0;r1 < n;r1++){ 52 for(r2 = 0;r2 < m;r2++){ 53 cin>>cmd; 54 if(cmd == '.') { 55 j[r1][r2] = 1; 56 room[r1][r2] = 1; 57 total++; 58 }else if(cmd == '#'){ 59 j[r1][r2] = 1; 60 room[r1][r2] = 0; 61 } 62 } 63 } 64 r1 = r2 =0; 65 for(r1 = 0;r1 < n;r1++){ 66 for(r2 = 0;r2 < m;r2++){ 67 if(room[r1][r2] && j[r1][r2]){ 68 j[r1][r2] = 0; 69 bfs(r1,r2); 70 } 71 72 } 73 } 74 cout<<total; 75 return 0; 76 }