https://www.acmicpc.net/problem/17141
연구소 3을 해결했다면 거저 먹을 수 있는 문제이다.
기본적으로 바이러스의 후보지들을 가지고 조합을 구해야 한다.
바이러스 후보지가 5곳이고 m = 3으로 주어진다면, 5Cm만큼의 경우의 수를 확인해보면 답을 찾을 수 있다.
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 81 82 83 84 85 86 87 88 89 | #include<iostream> #include<vector> #include<queue> #include<limits.h> using namespace std; int map[51][51], n, m, dis[51][51], st = 0, arr[11]; vector<pair<int, int> > v; bool isused[11]; queue<pair<int, int> >q; int dr[4] = { 0,0,1,-1 }; int dc[4] = { 1,-1,0,0 }; int res = INT_MAX; void init() { for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) dis[i][j] = -1; } pair<bool, int> check() { int Max = -2; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (dis[i][j] == -1 && map[i][j] == 0) return { false, -2 }; if (Max < dis[i][j]) Max = dis[i][j]; } } return { true, Max }; //바이러스가 완전히 확산된 경우만 시간 반환 } void bfs() { while (!q.empty()) { pair<int, int> cur = q.front(); q.pop(); for (int i = 0; i < 4; i++) { int nr = cur.first + dr[i]; int nc = cur.second + dc[i]; if (nr < 0 || nc < 0 || nr >= n || nr >= n) continue; if (map[nr][nc] == 1 || dis[nr][nc] >= 0) continue; q.push({ nr, nc }); dis[nr][nc] = dis[cur.first][cur.second] + 1; } } if (check().first) { int rtn = check().second; if (rtn < res) res = rtn; //반환된 시간의 최솟값 갱신 } } void backTracking(int k) { if (k == m) { for (int i = 0; i < m; i++) { //arr에 바이러스의 인덱스를 저장 q.push({ v[arr[i]].first, v[arr[i]].second }); dis[v[arr[i]].first][v[arr[i]].second]++; } bfs(); init(); //dis 초기화 return; } if (k == 0) st = 0; //조합 템플릿 for (int i = st; i < v.size(); i++) { if (!isused[i]) { arr[k] = i; isused[i] = true; st = i; backTracking(k + 1); isused[i] = false; } } } int main(void) { cin >> n >> m; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cin >> map[i][j]; if (map[i][j] == 2) v.push_back({ i, j }); } } init(); backTracking(0); if (res != INT_MAX) cout << res; //결과가 갱신된적이 없다면 제대로 확산된 적이 없는 것 else cout << -1; return 0; } | cs |
'알고리즘 문제 풀이 > 백준 온라인 저지' 카테고리의 다른 글
백준 15685번: 드래곤 커브 (C++) (0) | 2019.08.06 |
---|---|
백준 15686번: 치킨 배달 (C++) (0) | 2019.08.05 |
백준 11050번: 이항 계수1 (C++) (0) | 2019.08.05 |
백준 17142번: 연구소 3 (C++) (0) | 2019.08.05 |
백준 17143번: 낚시왕 (C++) (0) | 2019.08.04 |