ACDREAM 02G 小晴天老师系列——可恶的墨水瓶
Problem Description
小晴天老师正在备课,这时,可恶的墨水瓶突然自己打翻了!悲剧发生了!小晴天的备课稿都被墨水弄脏了。。。。
不过小晴天很乐观~这时他把他的一张纸分成n*m个格子,其中有一些格子被墨水涂黑了,有的没有。那么小晴天想知道,最大的一块联通的墨水块占多少个格子呢?
所谓的联通的即两个格子至少有一个公共顶点。
Input
多组数据,首先是一个正整数t(t<=20)
对于每组数据,先给出两个整数m.n(1<=n,m<=20)
然后是一个m行n列的01矩阵,若为1,则该格子被墨水染黑。
Output
对于每组数据,输出一个整数,表示最大被墨水染黑的连通格子数。
Sample Input
1
4 4
1 1 0 0
0 1 1 0
0 0 1 0
1 0 0 0
Sample Output
5
解题思路:找最大连通图,找完记得标记,下次被访问过的点就不能再访问了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#define N 25
using namespace std;
typedef long long ll;
int n, m;
int Max, head, tail, cnt;
int dir[8][2] = {{1, 0}, {1, -1}, {1, 1}, {0, 1}, {0, -1}, {-1, -1}, {-1, 1}, {-1, 0}};
int map[N][N];
struct pos{
int x, y;
}p[500], temp;
void BFS() {
while (head < tail) {
temp = p[head];
for (int i = 0; i < 8; i++) {
int px = temp.x + dir[i][0];
int py = temp.y + dir[i][1];
if (px < 0 || py < 0) continue;
if (px > n || py > m) continue;
if (map[px][py] == 1) {
p[tail].x = px;
p[tail].y = py;
tail++;
cnt++;
map[px][py] = 2;
}
}
head++;
}
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
memset(map, 0, sizeof(map));
scanf("%d %d", &n, &m);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
scanf("%d", &map[i][j]);
}
}
Max = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (map[i][j] == 1) {
cnt = 1;
head = tail = 0;
map[i][j] = 2;
p[head].x = i;
p[head].y = j;
tail++;
BFS();
Max = max(Max, cnt);
}
}
}
printf("%d\n", Max);
}
return 0;
}