https://www.acmicpc.net/problem/2636

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int n, m;
int dirX[4] = {-1, 0, 1, 0};
int dirY[4] = {0, 1, 0, -1};
vector<vector<int>> vec(100, vector<int> (100));
vector<vector<bool>> visited(100, vector<bool> (100, false));
int ans1 = 0;
int ans2;
int temp;
void bfs() {
while(true){
queue<pair<int, int>> q;
q.push({0,0});
visited[0][0] = true;
ans2 = temp;
temp = 0;
while(!q.empty()){
auto [x, y] = q.front();
q.pop();
for(int i=0; i<4; i++){
int nx = x + dirX[i];
int ny = y + dirY[i];
if(nx >= 0 && ny >= 0 && nx < n && ny < m && !visited[nx][ny]){
if(vec[nx][ny] == 1){
vec[nx][ny] = 0;
visited[nx][ny] = true;
temp++;
}
else if(vec[nx][ny] == 0){
visited[nx][ny] = true;
q.push({nx, ny});
}
}
}
}
if(temp != 0) ans1++;
else break;
fill(visited.begin(), visited.end(), vector<bool>(100, false));
}
cout << ans1 << "\n";
cout << ans2;
}
int main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
cin >> n >> m;
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
cin >> vec[i][j];
}
}
bfs();
return 0;
}
BFS안에서 while반복문을 두번 중첩한다. 첫번째 while문에서는 queue를 선언,
q에 (0,0)을 넣고 방문을 체크해준다. 두번째로 출력할 ans2 값에 temp를 저장하고, temp를 0으로 초기화한다. (temp는 사라질 치즈의 개수이다. 즉 치즈 겉면)
그 후 while문을 만들어 우리가 아는 bfs를 만들어주는데 공기와 치즈가 만나면 치즈가 있던 부분을 0으로 바꾸고 방문을 체크해주고 temp값을 1 증가시킨다. 공기와 공기를 만나면 방문을 체크하고 q에 넣어준다. 이러면 한번 bfs를 돌릴 때 마다 사라질 치즈의 갯수는 temp값에 저장된다. temp가 0이 아니면 ans1을 1 증가시키고(ans1은 치즈가 녹아 없어질 시간) 방문벡터를 초기화해준다. temp가 0이면 더 이상 사라질 치즈가 없기 때문에 break 해준다.
그러면 ans1에는 녹아 없어지는데 걸리는 시간이, ans2에는 녹아 없어지기전 마지막에 남아있던 치즈의 갯수가 잘 저장되어 있을 것이다.