서울 지하철 2호선

aram_father·2022년 1월 14일
0

Beakjoon Online Judge

목록 보기
83/84
post-thumbnail

DFS를 활용해서 그래프에서 사이클에 포함된 정점들을 검출한 뒤 해당 정점의 dist를 0로 초기화하여 Dijkstra를 통해 풀어주었다.

무방향 그래프에서 DFS를 통한 사이클 검출에 은근히 애를 먹었는데, 인점한 정점이 부모 였을 경우는 사이클로 치치 않아야 하는 것을 잊지 말도록 하자.

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

const int kMaxN = 3000;

int N;
vector<pair<int, int> > ADJ[kMaxN + 1];
bool VISIT[kMaxN + 1];
int PARENT[kMaxN + 1];
vector<int> CYCLE;

int ClearCycleEdges(const int u)
{
  VISIT[u] = true;
  for (auto& neighbor : ADJ[u])
  {
    const int v = neighbor.second;
    if (PARENT[u] == v)
    {
      continue;
    }
    else if (VISIT[v])
    {
      int src = u;

      while (true)
      {
        CYCLE.emplace_back(src);
        if (src == v)
        {
          break;
        }
        else
        {
          src = PARENT[src];
        }
      }

      return v;
    }
    else
    {
      PARENT[v] = u;
      int ret = ClearCycleEdges(v);
      if (ret != -1)
      {
        return ret;
      }
    }
  }

  return -1;
}

void Dijkstra(void)
{
  vector<int> dist(N + 1, 2 * N);
  priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > pq;

  for (auto v : CYCLE)
  {
    dist[v] = 0;
    pq.emplace(dist[v], v);
  }

  while (!pq.empty())
  {
    int cost = pq.top().first;
    int here = pq.top().second;
    pq.pop();

    if (dist[here] < cost)
    {
      continue;
    }

    for (const auto& neighbor : ADJ[here])
    {
      int weight = neighbor.first;
      int there = neighbor.second;

      if (dist[there] > weight + dist[here])
      {
        dist[there] = weight + dist[here];
        pq.emplace(dist[there], there);
      }
    }
  }

  for (int idx = 1; idx <= N; ++idx)
  {
    cout << dist[idx] << ' ';
  }
  cout << '\n';
}

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

  // Read Input
  cin >> N;
  for (int i = 0; i < N; ++i)
  {
    int src, dst;
    cin >> src >> dst;
    ADJ[src].emplace_back(1, dst);
    ADJ[dst].emplace_back(1, src);
  }

  // Solve
  ClearCycleEdges(1);
  Dijkstra();

  return 0;
}
profile
Pseudo-worker

0개의 댓글