어떤 박스를 쓰느냐에 따라서 달라진다.
DFS를 재귀적으로 표현하는 것이 더 편할 때도 있다.
p에서 시작했다고 치면 누군가 얘를 최초 호출해주는 애가 있어야 한다,
RDFS(p)
나머지는 재귀적으로 돌아간다.
global 마크 배열(모두 0으로 초기화)
1이 되면 마킹하는 것
노드마다 숫자를 2개 적는다.
pre = 1 / post =1 로 시작 (글로벌 변수)
pre(s) <- pre : pre++;
post(s) <- post: post++;
1씩 증가시켜준다.
각각 pre order / post order 로 번호를 붙인 것
s에 진입
s의 인접 노드인 t에 가기 직전에 t가 마킹이 안되어있으면 RDFS(t)를 호출
나와 인접한 노드를 넣기 전에 p*를 넣는다.
내가 넣은 노드가 다 뽑히면 p*가 나온다!
인접한 노드를 가지고 있다.
인접한 노드의 마킹을 check한다.
새로 marking하여 전진하면 child에 기록
s에 들어올때 이미 마킹이 되어있었다면 back에 기록
parent는 무시
Adj: 인접노드
Child: 전진한 노드
Parent: 부모 노드
Back: parent말고 이미 마킹되어있던 노드
다른 곳으로 전진하는 와중에 마킹된 것 (e)은 무시된다.
ex) b는 이미 마킹이 되어있어 s가 b를 back에 넣었듯이,
e의 입장에서 s는 이미 마킹이 되어있으므로 e가 s를 back을 넣었기 때문에
s입장에서 e는 무시된다.
back edges : 트리의 자손에서 조상으로 올라가는 길만 가능하다.
(방향성을 부여한 것을 설명을 위한 것)
그래프에서 잘 안풀리는 문제가 트리에서 쉽게 풀리는 이유라고 할 수 있음
back edge가 되는 것: 인접한 것 중에 들어왔을 때 이미 marking 되어 있는 것
ex) s->b
Q. b에 대해서 post를 했을까? (완전히 완료되었을까?)
A. b는 완료가 되었을 수 없다.
s에 들어왔을 때 b가 이미 마킹이 되어있다.
b는 종료가 안된 상태이기때문에 back에 들어온 것
조상과 자손을 잇는 형태만 가능하다.(b가 s의 자손)
또다른 back edge: "e는 s를 back에 넣는다." 도 같은 형태
(s가 e의 자손)
Bipartite Graph Detection
주어진 그래프가 Bipartite 그래프인지 확인한다.
두파트 그래프:
노드를 두 그룹으로 나눠서모든 엣지가 크로스로만 있도록 나눌 수 있다
Q. 엣지가 하나도 없다면 Bipartite 인가?
A. YES
- connected인지 확인 & 사이클이 없는지 확인 => 트리
or
- connected인지 확인 & 노드가 n개일 때 엣지 갯수가 반드시 n-1개
(사이클을 직접 체크하지 않아도 된다.)
루트를 무조건 왼쪽 그룹에 넣고 생각해보자.
루트와 연결된 노드는 무조건 오른쪽 그룹에 있어야 함
R와 L을 잇는 백엣지만 있어야 함
(같은 사이드에 있는 back edge가 하나라도 있으면 => NO)
'알고리즘' 카테고리의 다른 글
알고리즘21 (0) | 2020.11.14 |
---|---|
알고리즘20-2 Cut Vertex (0) | 2020.11.07 |
알고리즘19-2 (0) | 2020.11.07 |
알고리즘19 그래프 알고리즘 (0) | 2020.11.06 |
알고리즘18-2 완전 정보 게임 (0) | 2020.11.02 |