백준 17142번 연구소 3

#17142. 연구소 3

Problem

Solution

  • 퍼트릴 M개의 바이러스를 선택한다. (DFS)
    중복을 허용하지 않는 조합이다.
  • 선택한 바이러스를 퍼트리다. (BFS)
    4 방향으로 탐색을 하되, 빈 칸 또는 바이러스가 있는 곳이어야 한다.
  • dist라는 배열에 시간을 저장한다.
    단, 모서리에 있는 바이러스에서 탐색이 끝난 경우 시간을 1 빼주어야 한다.

1 Try

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <iostream>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
int N, M, ans = 1e9;
int map[50][50];
int selected[10];
int dx[4] = { -1, 1, 0, 0 };
int dy[4] = { 0, 0, -1, 1 };
vector<pair<int, int>> virus;
void Spread() {
bool visit[50][50] = { 0, };
int dist[50][50] = { 0, };
queue<pair<int, int>> q;
for (auto e : selected) {
if (e != -1) {
q.push({ virus[e].first, virus[e].second });
visit[virus[e].first][virus[e].second] = true;
}
}
while (!q.empty()) {
int x = q.front().first;
int y = q.front().second;
q.pop();
for (int dir = 0; dir < 4; ++dir) {
int d_x = x + dx[dir];
int d_y = y + dy[dir];
if (d_x < 0 || d_y < 0 || d_x >= N || d_y >= N) continue;
if (map[d_x][d_y] == 1 || visit[d_x][d_y]) continue;
visit[d_x][d_y] = true;
q.push({ d_x, d_y });
dist[d_x][d_y] = dist[x][y] + 1;
}
}
int time = 0;
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
if (dist[i][j] != 0 && map[i][j] == 2) {
if (i == 0 || j == 0 || i == N - 1 || j == N - 1)
dist[i][j]--;
}
if (!visit[i][j] && map[i][j] == 0) return;
if (dist[i][j] > time) time = dist[i][j];
}
}
if (ans > time) ans = time;
}
void SelectVirus(int idx, int cnt) {
if (cnt == M) {
Spread();
return;
}
for (int i = idx; i < virus.size(); ++i) {
selected[i] = i;
SelectVirus(i+1, cnt + 1);
selected[i] = -1;
}
}
int main() {
cin >> N >> M;
bool no_zero = true;
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
cin >> map[i][j];
if (map[i][j] == 2) virus.push_back({ i, j });
if (map[i][j] == 0) no_zero = false;
}
}
if (no_zero) {
cout << 0 << "\n";
}
else {
memset(selected, -1, sizeof(selected));
SelectVirus(0, 0);
if (ans != 1e9) cout << ans << "\n";
else cout << -1 << "\n";
}
return 0;
}