topological sort - changicho/algorithm-training GitHub Wiki

μœ„μƒμ •λ ¬

μ—°κ΄€ 문제

λ°±μ€€.2056.μž‘μ—…

λ°±μ€€.2252.쀄 μ„Έμš°κΈ°

μ„€λͺ…

μ‹œκ°„ λ³΅μž‘λ„ : O(V+E)

μœ„μƒ 정렬은 유ν–₯ λΉ„μˆœν™˜ κ·Έλž˜ν”„(Directed Acyclic Graph, DAG)μ—μ„œ μˆœμ„œκ°€ μ •ν•΄μ ΈμžˆλŠ” μž‘μ—… μ°¨λ‘€λ‘œ μˆ˜ν–‰ν•΄μ•Ό ν•  λ•Œ, κ·Έ μˆœμ„œλ₯Ό κ²°μ •ν•΄μ£ΌλŠ” μ•Œκ³ λ¦¬μ¦˜μ΄λ‹€.

vector<vector<int> > graph;
vector<int> inDegree; // index λ…Έλ“œμ—μ„œ 갈 수 μžˆλŠ” λ…Έλ“œμ˜ 개수
vector<int> result; // 정점을 λ°©λ¬Έν•˜λŠ” μˆœμ„œ

// μ§„μž… μ°¨μˆ˜κ°€ 0인 λ…Έλ“œλ₯Ό 큐에 μ‚½μž…ν•©λ‹ˆλ‹€
queue<int> q;
for (int node = 1; node <= N; node++) {
  if (inDegree[node] == 0) {
    q.push(node);
  }
}

// 정렬이 μ™„μ „νžˆ μˆ˜ν–‰λ˜λ €λ©΄ N개의 λ…Έλ“œλ₯Ό μ „λΆ€ λ°©λ¬Έν•©λ‹ˆλ‹€
for(int index = 0; index < N; index++) {
  if(q.empty()) {
    // n개λ₯Ό λ°©λ¬Έν•˜κΈ° 전에 큐가 비어버리면 사이클이 λ°œμƒν•œ 것
    // (이전에 μ§„μž…μ°¨μˆ˜κ°€ 0인 정점이 μ—†μ—ˆλ‹€λŠ” μ˜λ―Έμ΄λ―€λ‘œ)
    break;
  }

  int cur = q.front();
  q.pop();
  result[index] = cur;

  for(int next : graph[cur]) {
    inDegree[next]--;

    // μƒˆλ‘­κ²Œ μ§„μž…μ°¨μˆ˜κ°€ 0이 된 정점을 큐에 μ‚½μž…ν•©λ‹ˆλ‹€
    if(inDegree[next] == 0) {
      q.push(next);
    }
  }
}

μœ„μƒ 정렬을 μ΄μš©ν•œ νŠΉμ • μ •μ κΉŒμ§€ λ„λ‹¬ν•˜λŠ” μ΅œμ†Œ λΉ„μš©

μœ„μƒ 정렬을 μˆ˜ν–‰ν•˜λŠ” λ™μ•ˆ 각 index κΉŒμ§€ λ„λ‹¬ν•˜λŠ”λ° λ“€μ–΄κ°€λŠ” costλ₯Ό κ°±μ‹ ν•œλ‹€.

μ—¬κΈ°μ„œ ν˜„μž¬ μž‘μ—…κ³Ό μ—°κ²°λ˜μ–΄ μˆ˜ν–‰λ  μž‘μ—…μ„ 끝내기 μœ„ν•΄ μ†Œμš”λ˜λŠ” μ‹œκ°„μ€ μ΅œλŒ€ 값이 λ˜λ„λ‘ ν•΄μ•Όν•œλ‹€.

'μ²˜μŒλΆ€ν„° ν˜„μž¬ μž‘μ—…κΉŒμ§€λ₯Ό μ†Œμš”λ˜λŠ” μ‹œκ°„ + λ‹€μŒ μž‘μ—… ν•˜λ‚˜λ₯Ό λλ‚΄λŠ” 데 ν•„μš”ν•œ μ‹œκ°„' 값이 μ΅œλŒ€κ°€ λ˜μ–΄μ•Ό ν•œλ‹€.

μ˜ˆμ‹œλ‘œ μž‘μ—… Aλ₯Ό μˆ˜ν–‰ν•˜κΈ° μœ„ν•΄ B와 Cλ₯Ό μ„ ν–‰ν•΄μ•Ό ν•˜λŠ” 경우, B와 C쀑에 더 μ˜€λž˜κ±Έλ¦¬λŠ” μž‘μ—…μ„ μˆ˜ν–‰ν•΄μ•Ό ν•œλ‹€.

// costs : ν•΄λ‹Ή indexκΉŒμ§€ λ°©λ¬Έν•˜λŠ”λ° λ“€μ–΄κ°€λŠ” μ΅œμ†Œ λΉ„μš©
// times 각 μ •μ μ˜ λΉ„μš© (이전 μ •μ μ—μ„œ ν˜„μž¬ μ •μ κΉŒμ§€ λ„λ‹¬ν•˜λŠ” 데 λΉ„μš©)
vector<int> costs, times;
for (int node = 1; node <= N; node++) {
  costs[node] = times[node] = cost;
}

// λͺ¨λ“  λ…Έλ“œλ₯Ό λ°©λ¬Έν•˜μ§€ μ•Šμ•„λ„ 됨
while (!q.empty()) {
  int cur = q.front();
  q.pop();

  for (int next : graph[cur]) {
    times[next] = max(times[next], costs[next] + times[cur]);

    inDegree[next] -= 1;
    if (inDegree[next] == 0) {
      q.push(next);
    }
  }
}

for (int node = 1; node <= N; node++) {
  answer = max(answer, times[node]);
}
⚠️ **GitHub.com Fallback** ⚠️