텀 프로젝트

Wonseok Lee·2021년 8월 20일
0

Beakjoon Online Judge

목록 보기
24/117
post-thumbnail

Problem link: https://www.acmicpc.net/problem/9466

트리-like한 그래프가 주어질 때, 사이클에 포함된 노드의 수를 세는 문제로 볼 수 있다.

DFS를 진행할 때, 노드 X를 방문하고 노드 Y를 방문하려는데 이미 Y가 방문된 상태라고 해보자.

만약, 노드 Y가 아직 DFS가 완료되지 않은 지점이라면 노드 Y~X사이의 모든 노드는 사이클에 속한다.

적당히 VISIT 배열과 VISTI COUNT, 그리고 방문 이력을 잘 저장해주고 있으면 어렵지 않게 풀 수 있다.

#include <iostream>
#include <vector>

using namespace std;

size_t N;
vector<size_t> TABLE;

size_t VISIT_CNT;
vector<size_t> HISTORY;
vector<size_t> VISITED;
vector<bool> FINISHED;
vector<bool> IN_CYCLE;

void Dfs(const size_t vtx)
{
  VISITED[vtx] = ++VISIT_CNT;
  HISTORY[VISIT_CNT] = vtx;

  if (VISITED[TABLE[vtx]] == 0)
  {
    Dfs(TABLE[vtx]);
  }
  else if (!FINISHED[TABLE[vtx]])
  {
    for (size_t it = VISITED[TABLE[vtx]]; it <= VISITED[vtx]; ++it)
    {
      IN_CYCLE[HISTORY[it]] = true;
    }
  }

  FINISHED[vtx] = true;
}

size_t Solve(void)
{
  VISIT_CNT = 0;

  for (size_t it = 0; it < N; ++it)
  {
    if (VISITED[it] == 0)
    {
      Dfs(it);
    }
  }

  size_t sole = 0;
  for (size_t it = 0; it < N; ++it)
  {
    if (!IN_CYCLE[it])
    {
      ++sole;
    }
  }

  return sole;
}

int main(void)
{
  // For faster IO
  ios_base::sync_with_stdio(false);
  cout.tie(nullptr);
  cin.tie(nullptr);

  size_t tc;
  cin >> tc;

  while (tc--)
  {
    // Read input
    cin >> N;

    TABLE.assign(N, 0);

    VISITED.assign(N, 0);
    HISTORY.assign(N + 1, 0);  /// First is sentinel

    FINISHED.assign(N, false);
    IN_CYCLE.assign(N, false);

    for (size_t it = 0; it < N; ++it)
    {
      cin >> TABLE[it];
      --TABLE[it];
    }

    // Solve
    cout << Solve() << '\n';
  }

  return 0;
}
profile
Pseudo-worker

0개의 댓글