SlideShare una empresa de Scribd logo
1 de 47
Descargar para leer sin conexión
서울시립대 알고리즘 소모임
위상 정렬
2학기 4주차
강의자 소개
2021 AL林 정기 스터디
이름 최문기
소속 서울시립대 컴퓨터과학부(16학번)
핸들 iknoom1107(BOJ) IKnoom(Codeforces) IKnoom(AtCoder)
ICPC 팀 White Whale
- 김정현, 최문기, 오규민
2021 AL林 정기 스터디
위상 정렬
위상 정렬(Topological Sorting)
2021 AL林 정기 스터디
의존성이 있는 작업들이 주어질 때, 수행해야 하는 순서
유향 그래프의 정점을 방향을 거스르지 않도록 나열하는 것
(유향 그래프의 정점을 정렬하는 것)
“간선 (i, j)가 존재하면 정렬 결과에서 정점 i는 반드시 정점 j보다 앞에 위치해야 한다.”
위상 정렬(Topological Sorting)
2021 AL林 정기 스터디
“간선 (i, j)가 존재하면 정렬 결과에서 정점 i는 반드시 정점 j보다 앞에 위치해야 한다.”
정렬할 그래프는
1. 유향 그래프이며
2. 사이클이 없어야 합니다. (위 성질을 만족할 수 없죠)
※ 참고
2021 AL林 정기 스터디
이러한 그래프를
DAG(Directed Acyclic Graph)라고 합니다.
※ 의존성 그래프(dependency graph)라고 하기도 합니다
정렬할 그래프는
1. 유향 그래프이며
2. 사이클이 없어야 합니다.
위상 정렬의 예
2021 AL林 정기 스터디
1. 대학의 선수과목
2. 요리
3. 스타크래프트
등등...
위상 정렬의 예
2021 AL林 정기 스터디
위상 정렬의 예
2021 AL林 정기 스터디
점화
냄비에
물 넣기
라면
뜯기
라면
넣기
스프
넣기
계란
넣기
위상 정렬의 예
2021 AL林 정기 스터디
풀어볼 문제 줄 세우기(BOJ 2252번)
2021 AL林 정기 스터디
https://www.acmicpc.net/problem/2252
N명의 학생들을 키 순서대로 줄을 세우려고 한다.
각 학생의 키를 직접 재서 정렬하면 간단하겠지만, 마땅한 방법이 없어서 두 학생의 키를 비교하는 방법을 사용하
기로 하였다. 그나마도 모든 학생들을 다 비교해 본 것이 아니고, 일부 학생들의 키만을 비교해 보았다.
일부 학생들의 키를 비교한 결과가 주어졌을 때, 줄을 세우는 프로그램을 작성하시오.
풀어볼 문제 줄 세우기(BOJ 2252번)
2021 AL林 정기 스터디
[입력]
N = 3
M = 2
1 < 3
2 < 3
학생들의 번호는 1번부터 N번, M은 키를 비교한 회수
답이 여러 가지인 경우에는 아무거나 출력한다.
[출력]
1 2 3
풀어볼 문제 줄 세우기(BOJ 2252번)
2021 AL林 정기 스터디
[입력]
N = 8, M = 6
1 4
2 3
2 4
4 5
6 7
5 8
[출력]
1 2 3 4 6 5 7 8
2021 AL林 정기 스터디
위상 정렬 알고리즘
위상 정렬 알고리즘
2021 AL林 정기 스터디
알고리즘 1 Queue를 이용한 기본적인 방법 (BFS)
알고리즘 2 DFS를 이용한 방법
위상 정렬 알고리즘 ① : Queue
2021 AL林 정기 스터디
“진입 간선이 없는 정점을 선택하고 제거한다”
진입 간선 진출 간선
위상 정렬 알고리즘 ① : Queue
2021 AL林 정기 스터디
더 구체적으로
for i ← 1 to n {
① 진입 간선이 없는 정점 u를 선택한다.
② A[i] = u
③ 정점 u와 u의 진출 간선을 모두 제거한다.
}
return A[]
위상 정렬 알고리즘 ① : Queue
2021 AL林 정기 스터디
Answer
[ ]
위상 정렬 알고리즘 ① : Queue
2021 AL林 정기 스터디
Answer
[ 1 ]
위상 정렬 알고리즘 ① : Queue
2021 AL林 정기 스터디
Answer
[ 1 2 ]
위상 정렬 알고리즘 ① : Queue
2021 AL林 정기 스터디
Answer
[ 1 2 3 4 6 ]
위상 정렬 알고리즘 ① : Queue
2021 AL林 정기 스터디
Answer
[ 1 2 3 4 6 5 7 ]
위상 정렬 알고리즘 ① : Queue
2021 AL林 정기 스터디
Answer
[ 1 2 3 4 6 5 7 8 ]
위상 정렬 알고리즘 ① : Queue
2021 AL林 정기 스터디
아이디어는 쉽습니다.
하지만 어떻게 구현해야 효율적일까요?
위상 정렬 알고리즘 ① : Queue
2021 AL林 정기 스터디
for i ← 1 to n {
① 진입 간선이 없는 정점 u를 선택한다.
② A[i] = u
③ 정점 u와 u의 진출 간선을 모두 제거한다.
}
return A[]
위상 정렬 알고리즘 ① : Queue
2021 AL林 정기 스터디
Q = Queue()
INDEGREE = [0, 0, ..., 0]
1. 각 정점마다 진입 간선의 수를 INDEGREE에 저장한다.
2. 진입 간선이 없는 정점(INDEGREE[i] == 0)을 모두 Q에 넣는다.
위상 정렬 알고리즘 ① : Queue
2021 AL林 정기 스터디
result = List()
while (Q is not empty) {
① u = Q.pop()
② result.push(u)
③ for (u에 인접한 정점 v에 대해서){
INDEGREE[v] -= 1
if (INDEGREE[v] == 0) Q.push(v)
}
}
return result
위상 정렬 알고리즘 ① : 소스코드(python)
2021 AL林 정기 스터디
from collections import deque
N, M = map(int, input().split())
in_degree = [0] * (N + 1)
adj = [list() for _ in range(N)]
# 1. 각 정점마다 진입 간선의 수를 INDEGREE에 저장한다.
for _ in range(M):
u, v = map(int, input().split())
adj[u - 1].append(v - 1)
in_degree[v - 1] += 1
# 2. 진입 간선이 없는 정점(INDEGREE[i] == 0)을 모두 queue에 넣는다.
queue = deque()
for u in range(N):
if in_degree[u] == 0:
queue.append(u)
위상 정렬 알고리즘 ① : 소스코드(python)
2021 AL林 정기 스터디
# Topological Sorting
result = []
while len(queue) > 0:
u = queue.popleft()
result.append(u)
for v in adj[u]:
in_degree[v] -= 1
if in_degree[v] == 0:
queue.append(v)
# 출력
for u in result:
print(u + 1, end=' ')
위상 정렬 알고리즘 ① : 소스코드(python)
2021 AL林 정기 스터디
Queue 풀이 (소스코드 전체)
http://boj.kr/e6f76e4167714f60852b3cf559aaefad
위상 정렬 알고리즘 ② : DFS
2021 AL林 정기 스터디
사실 방금까지 한 위상 정렬은
DFS 종료 순서를 뒤집기만 하면 됩니다.
위상 정렬 알고리즘 ② : DFS
2021 AL林 정기 스터디
DFS(u) {
visited[u] = True
for (u에 인접한 정점 v에 대해서)
if (visited[v] = False) DFS(v)
result.push(u)
}
위상 정렬 알고리즘 ② : DFS
2021 AL林 정기 스터디
result = List()
for (모든 정점 u에 대해서)
visited[u] = False
for (모든 정점 u에 대해서)
if (visited[u] = False) DFS(u)
reverse(result) // result 를 뒤집는다.
return result
위상 정렬 알고리즘 ② : 소스코드(python)
2021 AL林 정기 스터디
import sys
sys.setrecursionlimit(10**9)
def dfs_ts(u):
visited[u] = True
for v in adj[u]:
if not visited[v]:
dfs_ts(v)
result.append(u)
위상 정렬 알고리즘 ② : 소스코드(python)
2021 AL林 정기 스터디
N, M = map(int, input().split())
adj = [list() for _ in range(N)]
for _ in range(M):
u, v = map(int, input().split())
adj[u - 1].append(v - 1)
visited = [False] * N
result = []
for u in range(N):
if not visited[u]:
dfs_ts(u)
result.reverse()
for u in result:
print(u + 1, end=' ')
위상 정렬 알고리즘 ② : 소스코드(python)
2021 AL林 정기 스터디
DFS 풀이 (소스코드 전체)
http://boj.kr/1db6303b1a6a47c48abc2723cf2b7cd9
위상 정렬 알고리즘 ② : DFS
2021 AL林 정기 스터디
이 방법은 먼저 알아본 방법에 비해서
상당히 비직관적입니다.
이 알고리즘의 정당성을 증명해볼까요?
위상 정렬 알고리즘 ② : DFS 정당성
2021 AL林 정기 스터디
귀류법으로 증명합니다. (알고리즘 문제 해결 전략 831페이지를 참고했습니다.)
위상 정렬 결과에서 역행하는 간선 (u,v)가 있다고 가정해봅시다.
위상 정렬 결과의 예 : {3, 2, ... , v, ... ,u, ..., 9, ...}
이 결과가 나오기 위해서는 dfs(u)가 종료한 후 dfs(v)가 종료했다는 것입니다.
dfs(u)는 종료 전에 인접한 간선을 모두 보기 때문에 (u,v) 또한 검사했을 것입니다.
위상 정렬 알고리즘 ② : DFS 정당성
2021 AL林 정기 스터디
이때 dfs(u)에서
1. visited[v]가 거짓일 경우
dfs(u)를 dfs(v)를 재귀 호출했을 것입니다.
따라서 dfs(v)가 종료된 후에 dfs(u)가 종료되었을 것이고 v는 u의 왼쪽에 있을 수 없습니다.
2. visited[v]가 참일 경우
dfs(v)는 이미 한번 호출되었어야 합니다.
그런데 dfs(v)가 dfs(u)보다 늦게 끝나기 위해서는, dfs(v)가 현재 실행 중이어야 합니다.
이렇게 되기 위해서는 v에서 u로 가는 경로가 필요합니다. (dfs(v) -> dfs(u)로 재귀호출)
하지만 그렇다면 그래프는 사이클을 형성합니다.
위상 정렬 알고리즘 ② : DFS
2021 AL林 정기 스터디
따라서 DFS로 얻어낸 위상 정렬의 결과에서
(u, v)인 간선이 있을 경우
u는 v의 왼쪽에 있을 수 밖에 없습니다!
2021 AL林 정기 스터디
참고
다시보기
2021 AL林 정기 스터디
result = List()
while (Q is not empty) {
① u = Q.pop()
② result.push(u)
③ for (u에 인접한 정점 v에 대해서){
INDEGREE[v] -= 1
if (INDEGREE[v] == 0) Q.push(v)
}
}
return result
큐의 크기를 통해서 알 수 있는 것
2021 AL林 정기 스터디
① 중간에 큐가 비어버리면 (루프가 N번 진행되지 않으면)
위상 정렬이 불가능한데 이 경우는 사이클이 있는 경우입니다.
(사이클이 있으면 위상정렬을 할 수 없다고 했죠.)
② 중간에 큐의 크기가 2 이상인 경우가 있다면
위상 정렬의 결과가 2개 이상입니다.
(큐에서 pop할 때 빼낼 수 있는 원소가 여러개라서 그렇습니다.)
earliest time
2021 AL林 정기 스터디
DP + Topological Sort
연습문제 : 작업 (BOJ 2056), ACM Craft (BOJ 1005)
https://www.acmicpc.net/problem/2056
https://www.acmicpc.net/problem/1005
critical path(임계경로)
2021 AL林 정기 스터디
A critical path is a longest path through the DAG, corresponding to the
longest time to perform any sequence of jobs. Thus, the weight of a critical
path provides a lower bound on the total time to perform all the jobs.
연습문제 : 임계경로 (BOJ 1948)
https://www.acmicpc.net/problem/1948
What’s New In Python 3.9
2021 AL林 정기 스터디
연습 문제
2020 AL林 정기 스터디
47
연습 문제
2252 줄 세우기
2623 음악프로그램
1766 문제집
3665 최종 순위
2056 작업
1005 ACM Craft

Más contenido relacionado

La actualidad más candente

1.자료구조와 알고리즘(강의자료)
1.자료구조와 알고리즘(강의자료)1.자료구조와 알고리즘(강의자료)
1.자료구조와 알고리즘(강의자료)
fmbvbfhs
 
이산수학 C1 프로젝트 4
이산수학 C1 프로젝트 4이산수학 C1 프로젝트 4
이산수학 C1 프로젝트 4
pkok15
 

La actualidad más candente (20)

2021 여름방학 정기 세미나 3주차
2021 여름방학 정기 세미나 3주차2021 여름방학 정기 세미나 3주차
2021 여름방학 정기 세미나 3주차
 
[신경망기초] 신경망의시작-퍼셉트론
[신경망기초] 신경망의시작-퍼셉트론[신경망기초] 신경망의시작-퍼셉트론
[신경망기초] 신경망의시작-퍼셉트론
 
1.자료구조와 알고리즘(강의자료)
1.자료구조와 알고리즘(강의자료)1.자료구조와 알고리즘(강의자료)
1.자료구조와 알고리즘(강의자료)
 
2020 여름방학 정기스터디 6주차
2020 여름방학 정기스터디 6주차2020 여름방학 정기스터디 6주차
2020 여름방학 정기스터디 6주차
 
알고리즘과 자료구조
알고리즘과 자료구조알고리즘과 자료구조
알고리즘과 자료구조
 
정수론적 알고리즘 - Sogang ICPC Team, 2020 Winter
정수론적 알고리즘 - Sogang ICPC Team, 2020 Winter정수론적 알고리즘 - Sogang ICPC Team, 2020 Winter
정수론적 알고리즘 - Sogang ICPC Team, 2020 Winter
 
[한양대 aloha] 프로그래밍 경진대회 문제_Advanced part
[한양대 aloha] 프로그래밍 경진대회 문제_Advanced part[한양대 aloha] 프로그래밍 경진대회 문제_Advanced part
[한양대 aloha] 프로그래밍 경진대회 문제_Advanced part
 
세그먼트 트리 느리게 업데이트하기 - Sogang ICPC Team, 2020 Winter
세그먼트 트리 느리게 업데이트하기 - Sogang ICPC Team, 2020 Winter세그먼트 트리 느리게 업데이트하기 - Sogang ICPC Team, 2020 Winter
세그먼트 트리 느리게 업데이트하기 - Sogang ICPC Team, 2020 Winter
 
차원축소 훑어보기 (PCA, SVD, NMF)
차원축소 훑어보기 (PCA, SVD, NMF)차원축소 훑어보기 (PCA, SVD, NMF)
차원축소 훑어보기 (PCA, SVD, NMF)
 
2020 2학기 정기스터디 2주차
2020 2학기 정기스터디 2주차2020 2학기 정기스터디 2주차
2020 2학기 정기스터디 2주차
 
R 프로그래밍-향상된 데이타 조작
R 프로그래밍-향상된 데이타 조작R 프로그래밍-향상된 데이타 조작
R 프로그래밍-향상된 데이타 조작
 
[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이
[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이
[D2 CAMPUS] 부산대 Alcall 프로그래밍 경시대회 문제 풀이
 
그래프의 최단 경로 찾기
그래프의 최단 경로 찾기그래프의 최단 경로 찾기
그래프의 최단 경로 찾기
 
이산수학04
이산수학04이산수학04
이산수학04
 
쏙 알고스터디 01
쏙 알고스터디 01쏙 알고스터디 01
쏙 알고스터디 01
 
퍼시스턴트 세그먼트 트리 - Sogang ICPC Team, 2020 Winter
퍼시스턴트 세그먼트 트리 - Sogang ICPC Team, 2020 Winter퍼시스턴트 세그먼트 트리 - Sogang ICPC Team, 2020 Winter
퍼시스턴트 세그먼트 트리 - Sogang ICPC Team, 2020 Winter
 
이산수학 C1 프로젝트 4
이산수학 C1 프로젝트 4이산수학 C1 프로젝트 4
이산수학 C1 프로젝트 4
 
Gmm to vgmm
Gmm to vgmmGmm to vgmm
Gmm to vgmm
 
[신경망기초] 소프트맥스회귀분석
[신경망기초] 소프트맥스회귀분석[신경망기초] 소프트맥스회귀분석
[신경망기초] 소프트맥스회귀분석
 
Linear algebra
Linear algebraLinear algebra
Linear algebra
 

Similar a 2021 2학기 정기 세미나 4주차 (6)

자료구조5보고서
자료구조5보고서자료구조5보고서
자료구조5보고서
 
Project#5 최단거리 찾기 D0 Hwp
Project#5 최단거리 찾기 D0 HwpProject#5 최단거리 찾기 D0 Hwp
Project#5 최단거리 찾기 D0 Hwp
 
알고리즘
알고리즘알고리즘
알고리즘
 
자료구조02
자료구조02자료구조02
자료구조02
 
하스켈로 알고리즘 문제 풀기 2
하스켈로 알고리즘 문제 풀기 2하스켈로 알고리즘 문제 풀기 2
하스켈로 알고리즘 문제 풀기 2
 
Efficient linear skyline algorithm in two dimensional space
Efficient linear skyline algorithm in two dimensional spaceEfficient linear skyline algorithm in two dimensional space
Efficient linear skyline algorithm in two dimensional space
 

Más de Moonki Choi (10)

2021 여름방학 정기 세미나 1주차
2021 여름방학 정기 세미나 1주차2021 여름방학 정기 세미나 1주차
2021 여름방학 정기 세미나 1주차
 
2021 알림 오세요
2021 알림 오세요2021 알림 오세요
2021 알림 오세요
 
2021 1학기 정기 세미나 3주차
2021 1학기 정기 세미나 3주차2021 1학기 정기 세미나 3주차
2021 1학기 정기 세미나 3주차
 
2021 1학기 정기 세미나 2주차
2021 1학기 정기 세미나 2주차2021 1학기 정기 세미나 2주차
2021 1학기 정기 세미나 2주차
 
2020 겨울방학 정기스터디 3주차
2020 겨울방학 정기스터디 3주차2020 겨울방학 정기스터디 3주차
2020 겨울방학 정기스터디 3주차
 
2020 겨울방학 정기스터디 2주차
2020 겨울방학 정기스터디 2주차2020 겨울방학 정기스터디 2주차
2020 겨울방학 정기스터디 2주차
 
2020 2학기 정기스터디 8주차
2020 2학기 정기스터디 8주차2020 2학기 정기스터디 8주차
2020 2학기 정기스터디 8주차
 
2020 2학기 정기스터디 1주차
2020 2학기 정기스터디 1주차2020 2학기 정기스터디 1주차
2020 2학기 정기스터디 1주차
 
2020 1학기 정기스터디 2주차
2020 1학기 정기스터디 2주차2020 1학기 정기스터디 2주차
2020 1학기 정기스터디 2주차
 
2020 1학기 정기스터디 1주차
2020 1학기 정기스터디 1주차2020 1학기 정기스터디 1주차
2020 1학기 정기스터디 1주차
 

2021 2학기 정기 세미나 4주차

  • 2. 강의자 소개 2021 AL林 정기 스터디 이름 최문기 소속 서울시립대 컴퓨터과학부(16학번) 핸들 iknoom1107(BOJ) IKnoom(Codeforces) IKnoom(AtCoder) ICPC 팀 White Whale - 김정현, 최문기, 오규민
  • 3. 2021 AL林 정기 스터디 위상 정렬
  • 4. 위상 정렬(Topological Sorting) 2021 AL林 정기 스터디 의존성이 있는 작업들이 주어질 때, 수행해야 하는 순서 유향 그래프의 정점을 방향을 거스르지 않도록 나열하는 것 (유향 그래프의 정점을 정렬하는 것) “간선 (i, j)가 존재하면 정렬 결과에서 정점 i는 반드시 정점 j보다 앞에 위치해야 한다.”
  • 5. 위상 정렬(Topological Sorting) 2021 AL林 정기 스터디 “간선 (i, j)가 존재하면 정렬 결과에서 정점 i는 반드시 정점 j보다 앞에 위치해야 한다.” 정렬할 그래프는 1. 유향 그래프이며 2. 사이클이 없어야 합니다. (위 성질을 만족할 수 없죠)
  • 6. ※ 참고 2021 AL林 정기 스터디 이러한 그래프를 DAG(Directed Acyclic Graph)라고 합니다. ※ 의존성 그래프(dependency graph)라고 하기도 합니다 정렬할 그래프는 1. 유향 그래프이며 2. 사이클이 없어야 합니다.
  • 7. 위상 정렬의 예 2021 AL林 정기 스터디 1. 대학의 선수과목 2. 요리 3. 스타크래프트 등등...
  • 8. 위상 정렬의 예 2021 AL林 정기 스터디
  • 9. 위상 정렬의 예 2021 AL林 정기 스터디 점화 냄비에 물 넣기 라면 뜯기 라면 넣기 스프 넣기 계란 넣기
  • 10. 위상 정렬의 예 2021 AL林 정기 스터디
  • 11. 풀어볼 문제 줄 세우기(BOJ 2252번) 2021 AL林 정기 스터디 https://www.acmicpc.net/problem/2252 N명의 학생들을 키 순서대로 줄을 세우려고 한다. 각 학생의 키를 직접 재서 정렬하면 간단하겠지만, 마땅한 방법이 없어서 두 학생의 키를 비교하는 방법을 사용하 기로 하였다. 그나마도 모든 학생들을 다 비교해 본 것이 아니고, 일부 학생들의 키만을 비교해 보았다. 일부 학생들의 키를 비교한 결과가 주어졌을 때, 줄을 세우는 프로그램을 작성하시오.
  • 12. 풀어볼 문제 줄 세우기(BOJ 2252번) 2021 AL林 정기 스터디 [입력] N = 3 M = 2 1 < 3 2 < 3 학생들의 번호는 1번부터 N번, M은 키를 비교한 회수 답이 여러 가지인 경우에는 아무거나 출력한다. [출력] 1 2 3
  • 13. 풀어볼 문제 줄 세우기(BOJ 2252번) 2021 AL林 정기 스터디 [입력] N = 8, M = 6 1 4 2 3 2 4 4 5 6 7 5 8 [출력] 1 2 3 4 6 5 7 8
  • 14. 2021 AL林 정기 스터디 위상 정렬 알고리즘
  • 15. 위상 정렬 알고리즘 2021 AL林 정기 스터디 알고리즘 1 Queue를 이용한 기본적인 방법 (BFS) 알고리즘 2 DFS를 이용한 방법
  • 16. 위상 정렬 알고리즘 ① : Queue 2021 AL林 정기 스터디 “진입 간선이 없는 정점을 선택하고 제거한다” 진입 간선 진출 간선
  • 17. 위상 정렬 알고리즘 ① : Queue 2021 AL林 정기 스터디 더 구체적으로 for i ← 1 to n { ① 진입 간선이 없는 정점 u를 선택한다. ② A[i] = u ③ 정점 u와 u의 진출 간선을 모두 제거한다. } return A[]
  • 18. 위상 정렬 알고리즘 ① : Queue 2021 AL林 정기 스터디 Answer [ ]
  • 19. 위상 정렬 알고리즘 ① : Queue 2021 AL林 정기 스터디 Answer [ 1 ]
  • 20. 위상 정렬 알고리즘 ① : Queue 2021 AL林 정기 스터디 Answer [ 1 2 ]
  • 21. 위상 정렬 알고리즘 ① : Queue 2021 AL林 정기 스터디 Answer [ 1 2 3 4 6 ]
  • 22. 위상 정렬 알고리즘 ① : Queue 2021 AL林 정기 스터디 Answer [ 1 2 3 4 6 5 7 ]
  • 23. 위상 정렬 알고리즘 ① : Queue 2021 AL林 정기 스터디 Answer [ 1 2 3 4 6 5 7 8 ]
  • 24. 위상 정렬 알고리즘 ① : Queue 2021 AL林 정기 스터디 아이디어는 쉽습니다. 하지만 어떻게 구현해야 효율적일까요?
  • 25. 위상 정렬 알고리즘 ① : Queue 2021 AL林 정기 스터디 for i ← 1 to n { ① 진입 간선이 없는 정점 u를 선택한다. ② A[i] = u ③ 정점 u와 u의 진출 간선을 모두 제거한다. } return A[]
  • 26. 위상 정렬 알고리즘 ① : Queue 2021 AL林 정기 스터디 Q = Queue() INDEGREE = [0, 0, ..., 0] 1. 각 정점마다 진입 간선의 수를 INDEGREE에 저장한다. 2. 진입 간선이 없는 정점(INDEGREE[i] == 0)을 모두 Q에 넣는다.
  • 27. 위상 정렬 알고리즘 ① : Queue 2021 AL林 정기 스터디 result = List() while (Q is not empty) { ① u = Q.pop() ② result.push(u) ③ for (u에 인접한 정점 v에 대해서){ INDEGREE[v] -= 1 if (INDEGREE[v] == 0) Q.push(v) } } return result
  • 28. 위상 정렬 알고리즘 ① : 소스코드(python) 2021 AL林 정기 스터디 from collections import deque N, M = map(int, input().split()) in_degree = [0] * (N + 1) adj = [list() for _ in range(N)] # 1. 각 정점마다 진입 간선의 수를 INDEGREE에 저장한다. for _ in range(M): u, v = map(int, input().split()) adj[u - 1].append(v - 1) in_degree[v - 1] += 1 # 2. 진입 간선이 없는 정점(INDEGREE[i] == 0)을 모두 queue에 넣는다. queue = deque() for u in range(N): if in_degree[u] == 0: queue.append(u)
  • 29. 위상 정렬 알고리즘 ① : 소스코드(python) 2021 AL林 정기 스터디 # Topological Sorting result = [] while len(queue) > 0: u = queue.popleft() result.append(u) for v in adj[u]: in_degree[v] -= 1 if in_degree[v] == 0: queue.append(v) # 출력 for u in result: print(u + 1, end=' ')
  • 30. 위상 정렬 알고리즘 ① : 소스코드(python) 2021 AL林 정기 스터디 Queue 풀이 (소스코드 전체) http://boj.kr/e6f76e4167714f60852b3cf559aaefad
  • 31. 위상 정렬 알고리즘 ② : DFS 2021 AL林 정기 스터디 사실 방금까지 한 위상 정렬은 DFS 종료 순서를 뒤집기만 하면 됩니다.
  • 32. 위상 정렬 알고리즘 ② : DFS 2021 AL林 정기 스터디 DFS(u) { visited[u] = True for (u에 인접한 정점 v에 대해서) if (visited[v] = False) DFS(v) result.push(u) }
  • 33. 위상 정렬 알고리즘 ② : DFS 2021 AL林 정기 스터디 result = List() for (모든 정점 u에 대해서) visited[u] = False for (모든 정점 u에 대해서) if (visited[u] = False) DFS(u) reverse(result) // result 를 뒤집는다. return result
  • 34. 위상 정렬 알고리즘 ② : 소스코드(python) 2021 AL林 정기 스터디 import sys sys.setrecursionlimit(10**9) def dfs_ts(u): visited[u] = True for v in adj[u]: if not visited[v]: dfs_ts(v) result.append(u)
  • 35. 위상 정렬 알고리즘 ② : 소스코드(python) 2021 AL林 정기 스터디 N, M = map(int, input().split()) adj = [list() for _ in range(N)] for _ in range(M): u, v = map(int, input().split()) adj[u - 1].append(v - 1) visited = [False] * N result = [] for u in range(N): if not visited[u]: dfs_ts(u) result.reverse() for u in result: print(u + 1, end=' ')
  • 36. 위상 정렬 알고리즘 ② : 소스코드(python) 2021 AL林 정기 스터디 DFS 풀이 (소스코드 전체) http://boj.kr/1db6303b1a6a47c48abc2723cf2b7cd9
  • 37. 위상 정렬 알고리즘 ② : DFS 2021 AL林 정기 스터디 이 방법은 먼저 알아본 방법에 비해서 상당히 비직관적입니다. 이 알고리즘의 정당성을 증명해볼까요?
  • 38. 위상 정렬 알고리즘 ② : DFS 정당성 2021 AL林 정기 스터디 귀류법으로 증명합니다. (알고리즘 문제 해결 전략 831페이지를 참고했습니다.) 위상 정렬 결과에서 역행하는 간선 (u,v)가 있다고 가정해봅시다. 위상 정렬 결과의 예 : {3, 2, ... , v, ... ,u, ..., 9, ...} 이 결과가 나오기 위해서는 dfs(u)가 종료한 후 dfs(v)가 종료했다는 것입니다. dfs(u)는 종료 전에 인접한 간선을 모두 보기 때문에 (u,v) 또한 검사했을 것입니다.
  • 39. 위상 정렬 알고리즘 ② : DFS 정당성 2021 AL林 정기 스터디 이때 dfs(u)에서 1. visited[v]가 거짓일 경우 dfs(u)를 dfs(v)를 재귀 호출했을 것입니다. 따라서 dfs(v)가 종료된 후에 dfs(u)가 종료되었을 것이고 v는 u의 왼쪽에 있을 수 없습니다. 2. visited[v]가 참일 경우 dfs(v)는 이미 한번 호출되었어야 합니다. 그런데 dfs(v)가 dfs(u)보다 늦게 끝나기 위해서는, dfs(v)가 현재 실행 중이어야 합니다. 이렇게 되기 위해서는 v에서 u로 가는 경로가 필요합니다. (dfs(v) -> dfs(u)로 재귀호출) 하지만 그렇다면 그래프는 사이클을 형성합니다.
  • 40. 위상 정렬 알고리즘 ② : DFS 2021 AL林 정기 스터디 따라서 DFS로 얻어낸 위상 정렬의 결과에서 (u, v)인 간선이 있을 경우 u는 v의 왼쪽에 있을 수 밖에 없습니다!
  • 41. 2021 AL林 정기 스터디 참고
  • 42. 다시보기 2021 AL林 정기 스터디 result = List() while (Q is not empty) { ① u = Q.pop() ② result.push(u) ③ for (u에 인접한 정점 v에 대해서){ INDEGREE[v] -= 1 if (INDEGREE[v] == 0) Q.push(v) } } return result
  • 43. 큐의 크기를 통해서 알 수 있는 것 2021 AL林 정기 스터디 ① 중간에 큐가 비어버리면 (루프가 N번 진행되지 않으면) 위상 정렬이 불가능한데 이 경우는 사이클이 있는 경우입니다. (사이클이 있으면 위상정렬을 할 수 없다고 했죠.) ② 중간에 큐의 크기가 2 이상인 경우가 있다면 위상 정렬의 결과가 2개 이상입니다. (큐에서 pop할 때 빼낼 수 있는 원소가 여러개라서 그렇습니다.)
  • 44. earliest time 2021 AL林 정기 스터디 DP + Topological Sort 연습문제 : 작업 (BOJ 2056), ACM Craft (BOJ 1005) https://www.acmicpc.net/problem/2056 https://www.acmicpc.net/problem/1005
  • 45. critical path(임계경로) 2021 AL林 정기 스터디 A critical path is a longest path through the DAG, corresponding to the longest time to perform any sequence of jobs. Thus, the weight of a critical path provides a lower bound on the total time to perform all the jobs. 연습문제 : 임계경로 (BOJ 1948) https://www.acmicpc.net/problem/1948
  • 46. What’s New In Python 3.9 2021 AL林 정기 스터디
  • 47. 연습 문제 2020 AL林 정기 스터디 47 연습 문제 2252 줄 세우기 2623 음악프로그램 1766 문제집 3665 최종 순위 2056 작업 1005 ACM Craft