πŸ“’  κ·Έλž˜ν”„μˆœνšŒ

  • 순회(Traversal) : λͺ¨λ“  정점과 간선을 κ²€μ‚¬ν•¨μœΌλ‘œμ¨ κ·Έλž˜ν”„λ₯Ό νƒν—˜ν•˜λŠ” 체계적인 절차
  • μ£Όμš”μ „λž΅

    πŸ‘‰ κΉŠμ΄μš°μ„ νƒμƒ‰(DFS, Depth First Search)
    πŸ‘‰ λ„ˆλΉ„μš°μ„ νƒμƒ‰(BFS, Breadth First Search)

πŸ“’  κΉŠμ΄μš°μ„ νƒμƒ‰(DFS)

  • κΉŠμ΄μš°μ„ νƒμƒ‰(DFS, Depth First Search) : κ·Έλž˜ν”„λ₯Ό μˆœνšŒν•˜κΈ° μœ„ν•œ 일반적 기법 쀑 ν•˜λ‚˜.
  • κ·Έλž˜ν”„ G에 λŒ€ν•œ DFS순회둜 κ°€λŠ₯ν•œ 것듀

    πŸ‘‰ G의 λͺ¨λ“  정점과 간선을 λ°©λ¬Έ
    πŸ‘‰ Gκ°€ μ—°κ²°κ·Έλž˜ν”„μΈμ§€ κ²°μ •
    πŸ‘‰ G의 μ—°κ²°μš”μ†Œλ“€μ„ 계산
    πŸ‘‰ G의 μ‹ μž₯μˆ²μ„ 계산

  • N개의 정점과 M개의 간선을 가진 κ·Έλž˜ν”„μ— λŒ€ν•œ DFSλŠ” O(N + M)μ‹œκ°„ μ†Œμš”
  • DFSλ₯Ό ν™•μž₯ν•˜λ©΄ ν•΄κ²° κ°€λŠ₯ν•œ κ·Έλž˜ν”„ λ¬Έμ œλ“€

    πŸ‘‰ 두 개의 주어진 정점 μ‚¬μ΄μ˜ 경둜λ₯Ό μ°Ύμ•„ 보기
    πŸ‘‰ κ·Έλž˜ν”„ λ‚΄ 싸이클 μ°ΎκΈ°

  • κ·Έλž˜ν”„μ— λŒ€ν•œ DFSλŠ” μ΄μ§„νŠΈλ¦¬μ— λŒ€ν•œ μ„ μœ„μˆœνšŒμ™€ μœ μ‚¬ν•˜λ‹€. ( μ„ μœ„μˆœνšŒλŠ” μž¬κ·€, 즉 μŠ€νƒ(Stack)을 ν™œμš©ν•œλ‹€. )
    ( 자료ꡬ쑰 μŠ€νƒμ„ λͺ¨λ₯Έλ‹€λ©΄, μ•„λž˜ ν¬μŠ€νŒ…μ„ 보고였길 λ°”λž€λ‹€. )
 

μŠ€νƒ(Stack) 자료ꡬ쑰

μŠ€νƒ(Stack) 자료ꡬ쑰 μŠ€νƒμ€ ν”νžˆ ν”„λ§κΈ€μŠ€μ— λΉ„μœ κ°€ λœλ‹€. ν”„λ§κΈ€μŠ€ 톡 μ•ˆμ— 감자칩이 μŒ“μ—¬μžˆμ§€λ§Œ μš°λ¦¬λŠ” κ°€μž₯ μœ„μ— μžˆλŠ” κ°μžμΉ©λΆ€ν„° κΊΌλ‚΄λŠ” 수 밖에 μ—†λ‹€. 즉, λ§ˆμ§€λ§‰μœΌλ‘œ 넣은 것이 (λ§¨μœ„μ— 있

velog.io

Alg DFS(G)
	input graph G
    output labeling of the edges of G 
    as tree edges and back edges

for each u ∈ G.vertexs()
	l(u) <- Fresh
for each e ∈ G.edges()
	l(e) <- Fresh
for each v ∈ G.vertexs()
	if(l(v) == Fresh)
    	rDFS(G,v)		// μž¬κ·€μ  DFS 호좜

=======================================================

Alg rDFS(G,V)		// μž¬κ·€μ  DFS
	input graph G and a start vertex v of G
    output labeling of the edges of G in the connected 
    component of v as tree edges and back edges
    
l(v) <- Visited		// λ°©λ¬Έν•œ λ…Έλ“œ 체크

for each e ∈ G.incidentEdges(v)		// 정점 v에 λΆ€μ°©λœ 간선에 λŒ€ν•΄
	if(l(e) == Fresh)			// κ°„μ„  eκ°€ 아직 μ•ˆμ§€λ‚˜κ°„ 간선이면
    	w <- G.opposite(v,e)			// 정점 v와 κ°„μ„  eλ₯Ό ν†΅ν•œ λ°˜λŒ€νŽΈ 정점 w
        if(l(w) == Fresh)			// wκ°€ 아직 λ―Έλ°©λ¬Έ 정점이면			
        	l(e) <- Tree			// 일단, κ°„μ„  eλŠ” Fresh -> Tree κ°„μ„ μœΌλ‘œ λ³€κ²½
            rDFS(G,w)				// rDFS μž¬κ·€ν˜ΈμΆœ
        else						// κ°„μ„  eκ°€ Freshν•œ 간선이 μ•„λ‹ˆλ‹€ ?
        	l(e) <- Back			// 그럼, κ°„μ„  eλŠ” Fresh -> Back κ°„μ„ μœΌλ‘œ λ³€κ²½

 

  • DFS μˆ˜ν–‰ μ˜ˆμ‹œ

DFS 처리 μ˜ˆμ‹œ

  • DFS 속성

    πŸ‘‰ 속성 1. rDFS(G,v)λŠ” v의 μ—°κ²°μš”μ†Œλ‚΄μ˜ λͺ¨λ“  정점과 간선을 λ°©λ¬Έν•œλ‹€.
    πŸ‘‰ 속성 2. rDFS(G,V)에 μ˜ν•΄ 라벨된 트리 간선듀은 v의 μ—°κ²°μš”μ†Œμ˜ μ‹ μž₯트리(DFS tree)λ₯Ό ν˜•μ„±ν•œλ‹€.
  • DFS 뢄석

    πŸ‘‰ 정점과 κ°„μ„ μ˜ 라벨을 μ“°κ³  μ½λŠ”λ° O(1)μ‹œκ°„ μ†Œμš”
    πŸ‘‰ 각 정점은 두 번 라벨 ( ν•œ λ²ˆμ€ Fresh, 또 ν•œλ²ˆμ€ Visited )
    πŸ‘‰ 각 간선은 두 번 라벨 ( ν•œ λ²ˆμ€ Fresh, 또 ν•œλ²ˆμ€ Tree λ˜λŠ” Back 으둜 )
    πŸ‘‰ incidentEdges( ) ( ν•œ 정점에 λΆ™μ–΄μžˆλŠ” λΆ€μ°©κ°„μ„  λ©”μ†Œλ“œ )λŠ” 각 정점에 λŒ€ν•΄ ν•œ 번 호좜
    πŸ‘‰ κ·Έλž˜ν”„κ°€ μΈμ ‘λ¦¬μŠ€νŠΈ ꡬ쑰둜 ν‘œν˜„λœ 경우, DFSλŠ” O(N + M)μ‹œκ°„μ— μˆ˜ν–‰ ( μ–΄λ–€ κ·Έλž˜ν”„ G의 deg(v) ν•© = 2M )

  • DFS ν…œν”Œλ¦Ώ ν™œμš©

    πŸ‘‰ μ—°κ²°μ„± 검사, 경둜 μ°ΎκΈ°, 싸이클 μ°ΎκΈ° λ“±μ˜ λ¬Έμ œλ“€μ„ DFSλ₯Ό ν™•μž₯ν•΄μ„œ ν•΄κ²°ν•  수 μžˆλ‹€.

πŸ“’  λΉ„μž¬κ·€μ  DFS

  • rDFS ( μž¬κ·€ DFS )λŠ” 이름 κ·ΈλŒ€λ‘œ, μž¬κ·€ν˜ΈμΆœμ„ ν†΅ν•΄μ„œ κ·Έλž˜ν”„ 순회λ₯Ό ν•œλ‹€.
  • λΉ„μž¬κ·€μ  DFSλŠ” μž¬κ·€ν˜ΈμΆœμ΄ μ•„λ‹Œ, μŠ€νƒ(Stack)을 μ‚¬μš©ν•΄μ„œ DFSλ₯Ό μ‹€ν–‰ν•œλ‹€.
Alg DFS(G,v)
	input graph G and a start vertex v of G
    output labeling of the edges of G 
    in the connected component of v
    as tree edges and back edges

S <= empty stack
S.push(v)		// λ§€κ°œλ³€μˆ˜ v정점 μŠ€νƒμ— push

while(!(S.isEmpty())	// μŠ€νƒμ„ λΉ„μšΈλ™μ•ˆ
	v <= S.pop()		// μŠ€νƒ pop()
	l(v) <- Visited		// pop()ν•œ μ •μ λŠ”,이제 Visited
    for each e ∈ G.incidentEdges(v)	// pop()ν•œ 정점에 λΆ€μ°©λœ λͺ¨λ“  간선에 λŒ€ν•΄
		if(l(e) == Fresh)			// κ·Έ 간선이 아직 λ°©λ¬Έμ•ˆν•œ 간선이면
        	w <- G.opposite(v,e)	// pop()ν•œ 정점 v와 μ—°κ²°λœ κ°„μ„  e의 λ°˜λŒ€νŽΈ 정점이 w
            if(l(w) == Fresh)		// κ·Έ 정점 wκ°€ 아직 λ°©λ¬Έμ•ˆν•œ 정점이면 ?
            	l(e) <- Tree		// κ±΄λ„ˆμ–Έ κ°„μ„  eλŠ” 일단 Fresh -> Tree κ°„μ„ μœΌλ‘œ λ³€κ²½
                S.push(w)			// 그리고, w정점을 μŠ€νƒμ— push
            else					// 정점 wκ°€ 이미 λ°©λ¬Έν•œ 정점이면
            	l(e) <- Back		// κ±΄λ„ˆμ˜¨ κ°„μ„  eλŠ” Fresh -> Back κ°„μ„ μœΌλ‘œ λ³€κ²½ ( 싸이클 μ œμ–΄ )
return
  • μ‹€μ œ κ΅¬ν˜„ ( By. C )
// DFS λΉ„μž¬κ·€λ²„μ Ό

#include <stdio.h>
#include <stdlib.h>

typedef struct incidentedge
{
	int key;
	char state[6];
	struct incidentedge* next;
	struct incidentedge* prev;
}IncidentEdge;
typedef struct vertex
{
	int key;
	char state[6];
	IncidentEdge* head;
}Vertex;
typedef struct stack						// λΉ„μž¬κ·€ DFSλ₯Ό μœ„ν•œ stack ( μ •μ μ˜ 킀값을 μ €μž₯할것이닀. )
{
	int* list;
	int top;
}Stack;

void nrDFS(Vertex* V, int S, int n);		// λΉ„μž¬κ·€ DFS
void makeVertex(Vertex* V, int n);
void linkEdge(Vertex* V, int start, int end);
void initStack(Stack* S, int n);			// μŠ€νƒ μ΄ˆκΈ°ν™”
void push(Stack* S, int n);					// μŠ€νƒ push
int pop(Stack* S);							// μŠ€νƒ pop
int isStackEmpty(Stack* S);					// μŠ€νƒ λΉ„μ—ˆλŠ”κ°€ ?
void freeVertexIncidentList(Vertex* V, int n);

int main()									
{
	int N, M, S, start, end;
	Vertex* v = NULL;
	scanf("%d %d %d", &N, &M, &S);

	v = (Vertex*)malloc(sizeof(Vertex) * N);

	makeVertex(v, N);

	for (int i = 0; i < M; i++)
	{
		scanf("%d %d", &start, &end);
		linkEdge(v, start, end);
		linkEdge(v, end, start);
	}
	nrDFS(v,S,N);							// λΉ„μž¬κ·€ DFS 호좜만 λ‹€λ₯Έ λΆ€λΆ„
	
	freeVertexIncidentList(v, N);			// 각 정점에 달린, 인접 리슀트 동적할당 ν•΄μ œ
	for (int i = 0; i < N; i++)
		free(v[i].head);					// 각 정점에 달린, μΈμ ‘ν—€λ“œ 동적할당 ν•΄μ œ
	free(v);								// 정점배열 동적할당 ν•΄μ œ
	return 0;
}
void nrDFS(Vertex* V,int s,int n)			// λΉ„μž¬κ·€μ  DFS
{
	IncidentEdge* p = NULL;					// μΈμ ‘λ¦¬μŠ€νŠΈ 쑰사할 p
	Stack* stack = NULL;					// μŠ€νƒ 포인터					
	
	stack = (Stack*)malloc(sizeof(Stack));	// μŠ€νƒ 동적할당
	initStack(stack,n);						// μŠ€νƒ μ΄ˆκΈ°ν™”
	
	push(stack, V[s - 1].key);				// νŒŒλΌλ―Έν„°λ‘œ λ„˜μ–΄μ˜¨ s, 정점 sλΆ€ν„° μ‹œμž‘, μŠ€νƒμ— push
	strcpy(V[s - 1].state, "visit");		// 정점 s λŠ” 이제 visit
	printf("%d\n", V[s-1].key);				// λ°©λ¬Έμ˜λ―Έν•˜λŠ” 좜λ ₯
	
	while (!isStackEmpty(stack))			// μ΄μ œλΆ€ν„° μŠ€νƒμ΄ λΉ„μšΈ λ•ŒκΉŒμ§€ λ°˜λ³΅ν•  κ²ƒμž„
	{
		// 맀 μ°¨λ‘€λ§ˆλ‹€
		p = V[stack->list[stack->top]-1].head->next;	// μŠ€νƒμ— κ°€μž₯ μ΅œκ·Όμ— λ“€μ–΄μ˜¨, μ •μ μœ„μΉ˜μ˜, μΈμ ‘λ…Έλ“œ μ‹œμž‘μ„ p에 λŒ€μž…ν•΄μ„œ	
		while (p != NULL && strcmp(V[p->key - 1].state, "visit") == 0)	// 인접해 μžˆλŠ”λ°, 아직 λ°©λ¬Έμ•ˆν•œ, 정점 찾음
			p = p->next;
		if (p != NULL && strcmp(V[p->key-1].state,"fresh") == 0)	// 아직 λ°©λ¬Έμ•ˆν•œ, μΈμ ‘ν•œ 정점이 있으면
		{
			push(stack, V[p->key - 1].key);				// κ·Έ 정점, μŠ€νƒμ— push
			strcpy(V[p->key - 1].state, "visit");		// κ·Έ 정점은 이제, visit
			printf("%d\n", V[p->key - 1].key);			// κ·Έ μ •μ μœΌλ‘œ, λ°©λ¬Έν–ˆμŒμ„ 의미,좜λ ₯
		}
		if (p == NULL)		// μœ— while문을 ν†΅ν•΄μ„œ, ν˜„μž¬ stack에 peekν•œ μ •μ μ˜, 인접 정점을 λ‹€ λ°©λ¬Έν–ˆμœΌλ©΄
			pop(stack);		// κ·Έ 정점은, 이제 λ“€μ–΄κ°ˆ 만큼 λ“€μ–΄κ°„ κ²ƒμ΄λ‹ˆ, pop
	}
	free(stack->list);	// μŠ€νƒ 리슀트 동적할당 ν•΄μ œ
	free(stack);	// μŠ€νƒ 동적할당 ν•΄μ œ
}
void makeVertex(Vertex* V, int n)
{
	for (int i = 0; i < n; i++)
	{
		V[i].key = i + 1;
		strcpy(V[i].state, "fresh");
		V[i].head = (IncidentEdge*)malloc(sizeof(IncidentEdge));
		if (V[i].head != NULL)
		{
			V[i].head->next = NULL;
			V[i].head->key = 0;
		}
	}
}
void linkEdge(Vertex* V, int start, int end)
{
	IncidentEdge* p, * newNode;
	
	newNode = (IncidentEdge*)malloc(sizeof(IncidentEdge));
	if (newNode != NULL)
	{
		newNode->key = end;
		newNode->prev = NULL;
		newNode->next = NULL;
		strcpy(newNode->state, "fresh");
	}
	p = V[start - 1].head;
	while (p->next != NULL && end > p->next->key)
		p = p->next;
	if (p->next == NULL)
	{
		p->next = newNode;
		newNode->prev = p;
	}
	else
	{
		newNode->next = p->next;
		p->next->prev = newNode;
		newNode->prev = p;
		p->next = newNode;
	}
}
void initStack(Stack* S, int n)
{
	S->list = (int*)malloc(sizeof(int) * n);
	S->top = -1;
}
void push(Stack* S, int n)
{
	S->top += 1;
	S->list[S->top] = n;
}
int pop(Stack* S)
{
	int returnData = S->list[S->top];
	S->top -= 1;
	return returnData;
}
int isStackEmpty(Stack* S)
{
	return S->top == -1;
}
void freeVertexIncidentList(Vertex* V, int n)
{
	IncidentEdge* p = NULL;

	for (int i = 0; i < n; i++)
	{
		while (V[i].head->next != NULL)
		{
			p = V[i].head->next;
			while (p->next != NULL) p = p->next;
			p->prev->next = NULL;
			free(p);
		}
	}
}

 

πŸ“’  λ„ˆλΉ„μš°μ„ νƒμƒ‰(BFS)

  • λ„ˆλΉ„μš°μ„ νƒμƒ‰(BFS, Breadth First Search) : κ·Έλž˜ν”„λ₯Ό μˆœνšŒν•˜κΈ° μœ„ν•œ 일반적 기법 쀑 ν•˜λ‚˜.
  • κ·Έλž˜ν”„ G에 λŒ€ν•œ BFS순회둜 κ°€λŠ₯ν•œ 것듀

    πŸ‘‰ G의 λͺ¨λ“  정점과 간선을 λ°©λ¬Έ
    πŸ‘‰ Gκ°€ μ—°κ²°κ·Έλž˜ν”„μΈμ§€ κ²°μ •
    πŸ‘‰ G의 μ—°κ²°μš”μ†Œλ“€μ„ 계산
    πŸ‘‰ G의 μ‹ μž₯μˆ²μ„ 계산

  • N개의 정점과 M개의 간선을 가진 κ·Έλž˜ν”„μ— λŒ€ν•œ BFSλŠ” O(N + M)μ‹œκ°„ μ†Œμš”
  • BFSλ₯Ό ν™•μž₯ν•˜λ©΄ ν•΄κ²° κ°€λŠ₯ν•œ κ·Έλž˜ν”„ λ¬Έμ œλ“€

    πŸ‘‰ 두 개의 주어진 정점 μ‚¬μ΄μ˜ μ΅œμ†Œ 간선을 μ‚¬μš©ν•˜λŠ” 경둜λ₯Ό 찾아보기
    πŸ‘‰ κ·Έλž˜ν”„ λ‚΄ λ‹¨μˆœμ‹Έμ΄ν΄ μ°ΎκΈ°

  • κ·Έλž˜ν”„μ— λŒ€ν•œ BFSλŠ” μ΄μ§„νŠΈλ¦¬μ— λŒ€ν•œ λ ˆλ²¨μˆœνšŒμ™€ μœ μ‚¬ν•˜λ‹€. ( λ ˆλ²¨μˆœνšŒλŠ” 큐(Queue)λ₯Ό ν™œμš©ν–ˆμ—ˆλ‹€. )
    ( 자료ꡬ쑰의 레벨순회λ₯Ό λͺ¨λ₯Έλ‹€λ©΄, μ•„λž˜ ν¬μŠ€νŒ…μ„ ν™•μΈν•˜κ³  였길 λ°”λž€λ‹€. )
 

[자료ꡬ쑰] 트리 - 레벨 순회

트리λ₯Ό μˆœνšŒν•˜λŠ” 방법은 보톡 μ „μœ„ 순회, μ€‘μœ„ 순회, ν›„μœ„ 순회 방식을 μ‚¬μš©ν•©λ‹ˆλ‹€. 트리 레벨 μˆœνšŒμ— λŒ€ν•΄ νŒŒμ•…ν•΄λ΄…μ‹œλ‹€. μš°μ„  트리의 레벨 순회 방법에 λŒ€ν•΄ μ•Œμ•„λ³΄κΈ° 이전에 트리의 λ ˆλ²¨λΆ€ν„°

coderush.tistory.com

Alg BFS(G)
	input graph G
    output labeling of the edges of G
	as tree edges and cross edges

for each u ∈ G.vertexs()
	l(u) <- Fresh
for each e ∈ G.edges()
	l(e) <- Fresh
for each v ∈ G.vertexs()
	if(l(v) == Fresh)
		BFS1(G,v)

=======================================

Alg BFS1(G,v)
	input graph G and a start vertex v of G
	output labeling of the edges of G
	in the connected component of v as tree
    edges and cross edges
    
L(0) <- empty list		// 레벨순회 큐(queue)
L(0).addLast(v)			// 큐에 λ§€κ°œλ³€μˆ˜λ‘œ λ„˜μ–΄μ˜¨, 정점 v λ₯Ό enqueue
l(v) <- Visited			// 정점을 큐에 enqueue ν–ˆλ‹€λŠ” 것은, λ°©λ¬Έν–ˆλ‹€λŠ” 의미. 고둜 정점 vλ₯Ό Fresh -> Visited
i <- 0					// 큐 인덱싱할 i

while(!(L(i).isEmpty())		// 큐λ₯Ό λΉ„μšΈλ•ŒκΉŒμ§€
	L(i+1) <- empty list
    for each v ∈ L(i).elements()	// 큐에 μžˆλŠ” 정점 ν•˜λ‚˜λ₯Ό dequeueλ₯Ό ν•˜κ³ 
    	for each e ∈ G.incidentEdges(v)	// κ·Έ 정점과 μ—°κ²°λœ λͺ¨λ“  간선에 λŒ€ν•΄
        	if(l(e) == Fresh)		// 아직 λ°©λ¬Έμ•ˆν•΄λ³Έ 간선이면 κ°€μ„œ
        		w <- G.opposite(v,e)	// κ·Έ 정점 v와 κ°„μ„  eλ₯Ό ν†΅ν•œ λ°˜λŒ€νŽΈ 정점을 w라 ν•˜κ³ 
            	if(l(w) == Fresh)		// κ·Έ 정점 wκ°€ 아직 λ°©λ¬Έμ•ˆν•œ 정점이면
            		l(e) <- Tree		// κ°„μ„  eλŠ” Fresh -> Tree κ°„μ„ μœΌλ‘œ
                	l(w) <- Visited)	// 정점 wλŠ” Fresh -> Visited μ •μ μœΌλ‘œ λ³€κ²½ν•˜κ³ 
                	L(i+1).addLast(w)	// 정점 wλ₯Ό 큐에 enqueue
				else					// 정점 wκ°€ 이미 λ°©λ¬Έν•œ 정점이라면
            		l(e) <- Cross		// κ°„μ„  eλŠ” Fresh -> Cross κ°„μ„ μœΌλ‘œ
	i <- i + 1

 

  • BFS μˆ˜ν–‰ μ˜ˆμ‹œ

BFS μˆ˜ν–‰ μ˜ˆμ‹œ

 

  • BFS 속성

    πŸ‘‰ G(v) : v의 μ—°κ²°μš”μ†ŒλΌ ν–ˆμ„ λ•Œ
    πŸ‘‰ 속성 1. BFS1(G,v)λŠ” G(v)의 λͺ¨λ“  정점과 간선을 λ°©λ¬Έν•œλ‹€.
    πŸ‘‰ 속성 2. BFS1(G,v)에 μ˜ν•΄ 라벨된 트리 간선듀은 G(v)의 μ‹ μž₯트리(BFS tree)라 λΆˆλ¦°λ‹€. ( T(v) )
    πŸ‘‰ 속성 3. L(i)λ‚΄μ˜ 각 정점 w에 λŒ€ν•΄

    1. T(v)의 vμ—μ„œ w둜 ν–₯ν•˜λŠ” κ²½λ‘œλŠ” i개의 간선을 가진닀.
    2. G(v)λ‚΄μ˜ vμ—μ„œ w둜 ν–₯ν•˜λŠ” λͺ¨λ“  κ²½λ‘œλŠ” μ΅œμ†Œ i개 간선을 가진닀.

  • BFS 뢄석

    πŸ‘‰ 정점과 κ°„μ„ μ˜ 라벨을 μ“°κ³  μ½λŠ”λ° O(1) μ‹œκ°„μ†Œμš”
    πŸ‘‰ 각 정점은 두 번 라벨 ( ν•œ λ²ˆμ€ Fresh둜 , 또 ν•œ λ²ˆμ€ Visited 둜 )
    πŸ‘‰ 각 간선은 두 번 라벨 ( ν•œ λ²ˆμ€ Fresh둜 , 또 ν•œ λ²ˆμ€ Tree λ˜λŠ” Cross 둜 )
    πŸ‘‰ 각 정점은 리슀트 L(i)에 ν•œ 번 μ‚½μž… ( μ—¬κΈ°μ„œ λ¦¬μŠ€νŠΈλŠ” 큐(queue)λ₯Ό 의미 )
    πŸ‘‰ incidentEdges( ) ( λΆ€μ°©κ°„μ„  λ©”μ†Œλ“œ )λŠ” 각 정점에 λŒ€ν•΄ ν•œ 번 호좜
    πŸ‘‰ κ·Έλž˜ν”„ Gκ°€ μΈμ ‘λ¦¬μŠ€νŠΈ ꡬ쑰둜 ν‘œν˜„λœ 경우, BFSλŠ” O(N + M)μ‹œκ°„μ— μˆ˜ν–‰

  • BFS ν…œν”Œλ¦Ώ ν™œμš©

    πŸ‘‰ G의 μ—°κ²°μš”μ†Œλ“€μ„ κ³„μ‚°ν•˜κΈ°
    πŸ‘‰ G의 μ‹ μž₯μˆ²μ„ κ³„μ‚°ν•˜κΈ°
    πŸ‘‰ Gλ‚΄μ˜ λ‹¨μˆœ 싸이클 μ°ΎκΈ° λ˜λŠ” Gκ°€ μˆ²μž„μ„ λ³΄κ³ ν•˜κΈ°
    πŸ‘‰ G의 주어진 두 정점에 λŒ€ν•΄, κ·Έ μ‚¬μ΄μ˜ μ΅œμ†Œ κ°„μ„ λ‘œ 이루어진 G λ‚΄μ˜ 경둜 μ°ΎκΈ°, λ˜λŠ” 그런 경둜 μ—†μŒμ„ μ°ΎκΈ°
    ( 즉, μ΅œλ‹¨ 경둜(Directed Path) 문제 ν™œμš© κ°€λŠ₯ )
728x90
λ°˜μ‘ν˜•

+ Recent posts