• 카테고리

    질문 & 답변
  • 세부 분야

    알고리즘 · 자료구조

  • 해결 여부

    해결됨

백준 1325, 교재 47번 문제 질문입니다.

24.01.26 19:45 작성 24.01.26 19:50 수정 조회수 157

0

교재에서는 bfs로 구현했는데 저는 dfs로 구현해봤습니다.

그랬더니 시간초과가 발생했네요. 제가 작성한 코드가 올바른답이긴하지만 시간초과가 발생하는건지, 아니면 그냥 틀린건지 궁금합니다. 또한 올바른답 이맞다면 왜 시간초과가 발생하는지(시간복잡도 차이가 왜 크게 나는지)도 궁금합니다.

 

#include <iostream>

#include <vector>

#include <queue>

using namespace std;

int maxdepth=-1;

vector<vector<int>> a;

vector<bool> visited;

void dfs(int k, int depth);

int main() {

ios::sync_with_stdio(false);

cin.tie(NULL);

cout.tie(NULL);

int n,m;

cin >> n >> m;

a.resize(n + 1);

visited = vector<bool>(n + 1, false);

for (int i = 0; i < m; i++) {

int s,e;

cin >> s >> e;

a[e].push_back(s);

}

vector<int> result(n + 1, 0);

for (int i = 1; i <= n; i++) {

dfs(i, 0);

result[i] = maxdepth;

maxdepth = -1;

fill(visited.begin(), visited.end(), false);

}

int realmax = -1;

for (int i = 1; i <= n; i++) {

if (result[i] > realmax)realmax = result[i];

}

for (int i = 1; i <= n; i++) {

if (realmax==result[i])cout<<i<<' ';

}

}

void dfs(int k, int depth) {

if (maxdepth < depth)maxdepth = depth;

visited[k] = true;

for (int i : a[k]) {

if (!visited[i]) {

dfs(i, depth + 1);

}

}

visited[k] = false;

}

 

답변 1

답변을 작성해보세요.

1

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.01.27

안녕하세요, 인프런 AI 인턴입니다.

주신 코드를 살펴보았습니다. 답변 드리기에 앞서, 코드가 올바른지에 대해서는 직접 실행하여 정답을 검증해야 하겠지만, 시간 초과의 문제는 다른 이유일 가능성이 큽니다.

시간 초과가 발생하는 경우는 주로 알고리즘의 시간 복잡도가 문제를 푸는데 요구되는 시간 제한을 초과할 때 발생합니다. DFS(깊이 우선 탐색)는 자료 구조의 특성상 불필요한 깊은 탐색을 많이 하게 되는 경우가 있습니다. 특히, 그래프가 밀집되어 있을 때(stack이 깊어질 때) 오버헤드가 커질 수 있습니다.

추가적으로, 각 노드를 방문할 때마다 visited 벡터를 fill 함수로 초기화하는 부분이 있다면, 해당 연산도 시간 복잡도에 영향을 줍니다. 이 경우, 각 노드를 시작으로 DFS를 할 때마다 O(N)의 시간 복잡도를 가지게 되므로, 전체 노드에 대해 수행하면 시간 복잡도가 O(N^2)가 됩니다.

상대적으로 BFS(너비 우선 탐색)는 매 탐색 시 불필요한 경로를 조기에 배제하면서 탐색을 진행하기 때문에, 간선의 개수에 비례하는 O(N + E)의 시간 복잡도를 가집니다. 따라서 BFS가 DFS보다 더 효율적인 경우가 많습니다.

코드 최적화를 위해서는 다음과 같은 방법을 시도해 볼 수 있습니다.

  1. visited 벡터를 매번 초기화하지 않고, DFS 호출 시 이전에 방문했던 노드를 기록하는 추가적인 방법을 사용해 볼 수 있습니다.
  2. 메모이제이션(Memoization)을 통해 이미 계산된 결과를 저장하고 재사용하여 중복 계산을 줄입니다.
  3. 각 노드간의 관계를 효율적으로 표현하는 자료 구조를 사용합니다. 예를 들어, 인접 리스트 대신 인접 행렬을 사용할 수 있습니다.

마지막으로, 실제 온라인 저지 시스템에서 답안 제출 시 시간 초과가 계속 발생한다면 다른 알고리즘으로 접근 방식을 바꿔 문제를 해결해야 할 수도 있습니다.