Study hard
(c++)백준 17141번: 연구소 2 본문
17141번: 연구소 2
인체에 치명적인 바이러스를 연구하던 연구소에 승원이가 침입했고, 바이러스를 유출하려고 한다. 승원이는 연구소의 특정 위치에 바이러스 M개를 놓을 것이고, 승원이의 신호와 동시에 바이
www.acmicpc.net
[풀이]
dfs 조합과 bfs flood fill을 사용하여 풀었다.
dfs를 사용하여 M개의 바이러스 위치의 조합을 구하고, 각 조합마다 bfs를 사용하여 바이러스가 연구소 전체에 퍼지는 시간을 구하였다.
bfs를 호출할 때마다 visited배열을 초기화하고, bfs가 끝나면 최소시간을 갱신해야한다.
#include <iostream>
#include <queue>
#include <vector>
#include <cstring>//memset
using namespace std;
struct Pos {
int x, y;
};
int N, M;
int Lab[50][50];
int visited[50][50];//bfs flood fill
bool check[50][50];//바이러스 놓았는지 확인
vector<Pos>Virus;
const int dx[] = { -1,1,0,0 };
const int dy[] = { 0,0,-1,1 };
int Min = 987654321;
bool Spread() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (Lab[i][j] != 1 && visited[i][j] == -1)
return false;
}
}
return true;
}
int bfs() {
queue<Pos>q;
int res = 0;
memset(visited, -1, sizeof(visited));
//바이러스가 있는 위치 모두 queue에 넣어주기
for (int i = 0; i < Virus.size(); i++) {
q.push({ Virus[i].x,Virus[i].y });
visited[Virus[i].x][Virus[i].y] = 0;
}
while (!q.empty()) {
int x = q.front().x;
int y = q.front().y;
q.pop();
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx < 0 || nx >= N || ny < 0 || ny >= N)
continue;
if (Lab[nx][ny] != 1 && visited[nx][ny] == -1) {
visited[nx][ny] = visited[x][y] + 1;
res = visited[nx][ny];
q.push({ nx,ny });
}
}
}
//마지막에 퍼뜨린 곳의 시간이 모든 빈 칸에 바이러스를 퍼뜨리는 최소 시간임
return res;
}
//바이러스 위치 조합 구하기
void dfs(int x, int y, int cnt) {
if (cnt == M) {
int res = bfs();
if (Spread() == true) {
if (Min > res)
Min = res;
}
return;
}
for (int i = x; i < N; i++) {
for (int j = y; j < N; j++) {
if (Lab[i][j] != 2 ||check[i][j] == true)
continue;
check[i][j] = true;
Virus.push_back({ i,j });
dfs(i, j, cnt + 1);
check[i][j] = false;
Virus.pop_back();
}
y = 0;
}
}
int main() {
cin >> N >> M;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cin >> Lab[i][j];
}
}
dfs(0, 0, 0);
if (Min == 987654321)
Min = -1;
cout << Min << '\n';
return 0;
}
'백준 > bfs, dfs' 카테고리의 다른 글
(c++)백준 12906번: 새로운 하노이 탑 (0) | 2021.02.16 |
---|---|
(c++)백준 2234번: 성곽 (0) | 2021.02.16 |
(c++)백준 1600번: 말이 되고픈 원숭이 (0) | 2021.02.12 |
(c++)백준 16946번: 벽 부수고 이동하기 4 (0) | 2021.02.07 |
(c++)백준 16236번: 아기 상어 (0) | 2020.10.17 |