문제
해커 김지민은 잘 알려진 어느 회사를 해킹하려고 한다. 이 회사는 N개의 컴퓨터로 이루어져 있다. 김지민은 귀찮기 때문에, 한 번의 해킹으로 여러 개의 컴퓨터를 해킹 할 수 있는 컴퓨터를 해킹하려고 한다.
이 회사의 컴퓨터는 신뢰하는 관계와, 신뢰하지 않는 관계로 이루어져 있는데, A가 B를 신뢰하는 경우에는 B를 해킹하면, A도 해킹할 수 있다는 소리다.
이 회사의 컴퓨터의 신뢰하는 관계가 주어졌을 때, 한 번에 가장 많은 컴퓨터를 해킹할 수 있는 컴퓨터의 번호를 출력하는 프로그램을 작성하시오.
입력
첫째 줄에, N과 M이 들어온다. N은 10,000보다 작거나 같은 자연수, M은 100,000보다 작거나 같은 자연수이다. 둘째 줄부터 M개의 줄에 신뢰하는 관계가 A B와 같은 형식으로 들어오며, "A가 B를 신뢰한다"를 의미한다. 컴퓨터는 1번부터 N번까지 번호가 하나씩 매겨져 있다.
출력
첫째 줄에, 김지민이 한 번에 가장 많은 컴퓨터를 해킹할 수 있는 컴퓨터의 번호를 오름차순으로 출력한다.
풀이
문제 자체는 어렵지 않았다. dfs를 이용하면 금방 해결되는 문제였지만 자꾸 메모리 초과가 나서 꽤 애를 먹었었다.
처음에는 dfs함수 안에서 재귀호출을 하도록 코드를 작성했었는데 그 부분때문에 메모리 초과가 나는거였다.
그래서 메인함수에서 반복문을 이용해 dfs함수를 호출하는 방법으로 수정하였다.
#include<vector>
#include<iostream>
#include<algorithm>
#include<stack>
#include<map>
#define _CRT_SECURE_NO_WARNINGS
using namespace std;
int n, m;
vector<int> res;
vector<vector<int>> arr;
int dfs(int start) {
vector<int> visited(arr.size());
stack<int> need_visit;
int cnt = 0;
int node = start;
need_visit.push(node);
while (!need_visit.empty()) {
int node = need_visit.top();
need_visit.pop();
if (visited[node] == 0) {
visited[node] = 1;
cnt++;
for (int i = 0; i < arr[node].size(); i++) {
need_visit.push(arr[node][i]);
}
}
}
res[start] = cnt;
return cnt;
}
int main() {
int max = 0;
cin >> n >> m;
arr.resize(n + 1);
res.resize(n + 1);
for (int i = 0; i < m; i++) {
int x, y;
cin >> x >> y;
arr[y].push_back(x);
}
for (int i = 1; i < n + 1; i++) {
int cnt = dfs(i);
if(max < cnt)
max = cnt;
}
for (int i = 1; i < n + 1; i++) {
if (res[i] == max)
cout << i << " ";
}
}
'알고리즘 > 백준 문제풀이' 카테고리의 다른 글
[백준 12761번] 돌다리 / C++ (0) | 2020.08.13 |
---|---|
[백준 1904번] 01타일 / C++ (0) | 2020.08.13 |
[백준 1012번] 유기농 배추 / C++ (0) | 2020.08.13 |
[백준 1439번] 뒤집기 / C++ (0) | 2020.08.12 |
[백준 2606번] 바이러스 / C++ (0) | 2020.08.12 |