Vue.js
1.0.0
1.0.0
  • README
  • Git
    • Basic
    • Remote Repository
    • Log & Diff
    • Rebase&Cherri-Pick
    • git-flow
  • DevOps
    • Monolithic vs MSA
    • Jenkins 시작하기
    • Airflow 시작하기
    • Airflow 시작하기
    • Build Tools
      • maven
  • 개발 방법론
    • TDD
  • Spring
    • IoC
    • Is Spring Bean Thread-Safe?
    • Spring Singleton
    • Component Scan
    • Spring Annotation
    • 의존 관계 주입(DI)
    • Lombok 활용하기
    • Bean 생명주기와 콜백
    • Bean Scope
    • AOP(1) - AOP란
    • AOP(2) - Aop Proxy
    • AOP(3) - Dynamic Proxy
    • AOP(4) - AspectJ
    • POJO
    • Spring 서비스 구조
    • Transaction
    • JPA란?
    • JPA Entity
    • Spring Data JPA
    • Spring Data Specification
    • Model Mapping
    • Cache
    • restTemplate
    • YAML 파일 설정
    • Spring Boot
      • H2 DB 설정
      • 다중 데이터베이스 설정
      • Mybatis 연동하기
    • Spring Batch
      • Batch 시작해보기
      • Batch Job Flow
      • Job
      • Step
      • Batch Scope & Job Parameter
      • JobRepository와 메타테이블
      • Chunk 지향 프로그래밍
      • ItemReader
      • ItemProcessor
      • ItemWriter
      • Batch Schedular
      • Job별 Bean등록하기
      • Batch 구현시 발생한 오류 정리
      • Spring Batch Scaling
        • Multithread Job구현시 이슈사항
    • Spring test
      • Junit5
        • 테스트 이름 표기
        • 테스트 그룹 사이의 관계
        • 태그와 필터링
        • 동적 테스트
        • 테스트 LifeCycle
        • 테스트 메서드
        • 테스트 순서
        • AssertJ
        • 테스트 병렬 실행
        • AssertJ
        • Mock
      • Spring Boot Test DB 분리
      • Spring Batch Test
  • Web Application
    • Web Server & WAS
    • 관련 개념 - HTTP API, HTML, CSR, SSR
    • Servlet
    • JSP
    • Cookie And Session
    • 예외페이지
    • Java Bean
    • JDBC
    • Connection Pool
    • 파일 업로드
    • Expression Language
    • JSTL
    • FrontController패턴 Command 패턴
    • Forwarding
    • MVC
    • 회원가입예제
    • 참고
      • 개발환경설정
  • Java+
    • SOAP/WSDL vs REST
    • WSDL을 JAVA로 변환하기
    • SOAP 통신 OPEN API로 개발해보기
  • Java
    • Basic
      • 변수와 타입
      • 연산자
      • 조건문과 반복문
      • 참조 타입
      • 클래스
      • 상속(Inheritance)
      • 인터페이스(Interface)
      • 중첩 클래스와 중첩 인터페이스
      • 예외 처리
      • API - Object, System, Class, Math, Wrapper
      • API - String, StringBuffer, StringBuilder
      • Thread
      • Generic
      • Lambda
      • Collection - List, Set
      • Collection - Map
      • Collection - Tree
      • Collection - Stack, Queue
      • Stream
      • Reflection
      • 정규표현식
      • GUI
      • UML
      • Serializable
    • Advanced
      • OutOfMemoryError
      • AutoValue
      • meta-annotation
        • @Retention
        • @Target
        • @Repeatable
    • Effective Java 3/E
      • ITEM 1: Static Factory Method(정적 메소드)
      • ITEM 2: Builder Pattern
      • ITEM 3: Singleton
      • ITEM 4: Private Constructor
      • ITEM 5: Dependency Injection
      • ITEM 6: Avoid Unnecessary Object
      • ITEM 7: Eliminate Object Reference
      • ITEM 8: Avoid finalizer and cleaner
      • ITEM 9: try-with-resources
      • ITEM 10: The gerneral contract when overriding equlas
      • ITEM 11: Overriding hashCode
      • ITEM 12: overriding toString
      • ITEM 13: overriding clone judiciously
      • ITEM 14: Consider implementing comparable
      • ITEM 15: 클래스와 멤버의 접근을 최소화해라
      • ITEM 16: Use Accessor methods
      • ITEM 17: 변경 가능성을 최소화해라(불변 클래스)
      • ITEM 18: 상속보단 컴포지션을 사용해라
      • ITEM 19: 상속을 고려해 설계하고 문서화해라
      • ITEM 20: 추상 클래스보다 인터페이스를 우선하라
      • ITEM 21: 인터페이스는 구현하는 쪽을 생각해 설계해라.
      • ITEM 22: 인터페이스는 타입을 정의하는 용도로만 사용해라
      • ITEM 23: 태그 달린 클래스보다 클래스 계층구조를 활용해라
      • ITEM 24: 멤버 클래스는 되도록 static으로 구현해라
      • ITEM 25: 톱레벨 클래스는 한 파일에 하나만 생성해라.
      • ITEM 26: Raw type은 사용하지 마라
      • ITEM 27: 비검사 경고를 제거해라
      • ITEM 28: 배열보다는 리스트를 사용해라
      • ITEM 29: 이왕이면 제네릭 타입으로 만들어라
      • ITEM 30: 이왕이면 제네릭 메서드로 만들어라
      • ITEM 31 : 한정적 와일드카드를 사용해 API 유연성을 높여라
      • ITEM 32: 제네릭과 가변인수를 함께 쓸 때는 신중해라
      • ITEM 33: 타입 안전 이종 컨테이너를 고려해라
      • ITEM 34: int 상수 대신 열거 타입을 사용해라
      • ITEM 35: ordinal 메서드 대신 인스턴스 필드를 사용해라
      • ITEM 36: 비트 필드 대신 EnumSet을 사용해라
      • ITEM 37: ordinal 인덱싱 대신 EnumMap을 사용해라
      • TEM 38 : 확장할 수 있는 열거타입이 필요하면 인터페이스를 사용해라
      • ITEM 39: 명명 패턴보다 애너테이션을 사용해라
      • ITEM 40: @Override 어노테이션을 일관되게 사용해라
      • ITEM 41: 정의하려는 것이 타입이라면 마커 인터페이스를 사용해라
      • ITEM 42: 익명 클래스보다는 람다를 사용해라
      • ITEM 43: 람다보다는 메서드 참조를 사용해라
      • ITEM 44: 표준 함수형 인터페이스를 사용해라
      • ITEM 45: 스트림은 주의해서 사용해라
      • ITEM 46: 스트림에서 부작용 없는 함수를 사용해라
      • ITEM 47: 반환 타입으로는 스트림보다 컬렉션이 낫다.
      • ITEM 48: 스트림 병렬화는 주의해서 사용해라
      • ITEM 49: 매개변수가 유효한지 검사해라
      • ITEM 50: 적시에 방어적 복사본을 만들어라
      • ITEM 51: 메서드 시그니처를 신중히 설계해라
      • ITEM 52: 다중정의는 신중히 사용해라
      • ITEM 53: 가변인수는 신중히 사용해라
      • ITEM 54: null이 아닌, 빈 컬렉션이나 배열을 반환해라
      • ITEM 55: Optional 반환은 신중하게 해라
      • ITEM 56: 공개된 API 요소에는 항상 주석을 작성해라
      • ITEM 57: 지역변수의 범위를 최소화해라
      • ITEM 58: 전통적인 for 문보다는 for-each문을 사용해라
      • ITEM 59: 라이브러리를 익히고 사용해라
      • ITEM 60: 정확한 답이 필요하다면 float와 double은 피해라
      • ITEM 61: 박싱된 기본 타입보다는 기본 타입을 사용해라
      • ITEM 62: 다른 타입이 적절하다면 문자열 사용을 피해라
      • ITEM 63: 문자열 연결은 느리니 주의해라
      • ITEM 64: 객체는 인터페이스를 사용해 참조해라
      • ITEM 65: 리플렉션보다는 인터페이스를 사용해라
      • ITEM 66: 네이티브 메서드는 신중히 사용해라
      • ITEM 67: 최적화는 신중히 해라
      • ITEM 68: 일반적으로 통용되는 명명 규칙을 따라라
    • 객체지향 설계 원칙(SOLID)
    • 디자인패턴
      • Strategy Pattern
      • Template Method Pattern
      • Factory Method Pattern
      • Singleton
      • Delegation
      • Proxy
      • Adapter Pattern
    • 실습
      • 인터페이스 실습 - Vehicle
      • 인터페이스 실습 - Remote
      • GUI 실습 - Calculator
      • GUI 실습 - button
      • GUI 실습 - lotto
      • Thread 실습 - 좌석예약, 메세지보내기
    • Jar vs War
  • 데이터베이스
    • KEY
    • Index
    • Transaction
    • Trigger
    • Procedure / Function
    • Package
    • 데이터베이스 배움터
      • 데이터베이스 시스템
      • 관계데이터 모델
      • 관계대수와 SQL
    • MySQL
      • Database란
      • MySQL 시작하기
      • MySQL Database
      • MySQL Table
      • CRUD
      • 관계형 데이터베이스
      • Server와 Client
    • PostgreSQL
    • NoSQL
      • Install Cassandra on mac
      • Cassandra란?
      • NiFi란
  • Algorithm
    • String
    • Recursion
    • Dynamic Programming
    • Array, Struct, Pointer
    • Math
    • Sort
    • List
    • Stack
    • Queue
    • Graph
    • Tree
    • Maze
    • AVL
    • 이진탐색트리(Binary Search Tree)
    • DFS와 BFS
    • 다익스트라 알고리즘(Dijkstra's Algorithm)
    • Red-Black 트리
    • A* 알고리즘
    • Heap
    • Huffman Coding
    • Priority Queue
    • Bellman-Ford 알고리즘
    • C++
      • Class
      • STL
        • STL pair
        • STL Container - Associate Container
        • STL Container - Sequence Container
        • STL Container - Container Adapter
  • JavaScript
    • JABASCRIPT BASIC
    • Shallow Copy vs Deep Copy
    • OBJECT MODEL
    • NODE
    • 동기 처리 vs 비동기 처리
    • AJAX
    • CALLBACK
    • PROMISE
    • DEFERRER
    • UNDERSCORE
    • WEBPACK
    • SCOPE
    • EXECUTION CONTEXT
    • Image Object
    • BFCache란?
    • history.scrollRestoration
    • Intersection Observer
    • JWT - JSON Web Token
    • HTML vs JSON
  • Vue.js
    • 환경설정
    • Vue.js란?
    • Vue Instance
    • Vue Component
    • Vue Router
    • HTTP 통신
    • Template
    • Single File Component
    • Vue Animation
    • Vuex
    • Djnago와 연동하기
  • Backbone.js
    • Model
    • Collection
    • Sync
    • view
  • Node.js
    • Doit! - 노드로 만들 수 있는 대표적인 서버와 용도
    • Doit! - 노드에 대해 알아보고 개발 도구 설치하기
    • Doit! - 노드 간단하게 살펴보기
    • Doit! - 노드의 자바스크립트와 친해지기
    • Doit! - 노드의 기본 기능 알아보기
    • Doit! - 웹 서버 만들기
    • Doit! - 데이터베이스 사용하기
    • Doit! - 익스프레스 프로젝트를 모듈화하기
    • Doit! - 뷰 템플릿 적용하기
    • Doit! - 패스포트로 사용자 인증하기
    • Doit! - 채팅서버 만들기
    • Doit! - JSON-RPC 서버 만들기
  • Python
    • Warning-Could not import the lzma module
    • Pandas
      • Pandas 자료구조
      • Pandas 데이터 입출력
      • DataFrame Data 살펴보기
      • 시각화 도구 - Matplotlib
  • ML
    • 추천 시스템
      • Collaborative Filtering
      • Matrix Factorization
  • Django
    • Basic
      • 환경설정
      • About Django
      • Start Django Project
      • Secret Key 관리하기
      • Settings 분리하기
      • Django App
      • Django View & URL (1)
      • Django Model
        • MySQL 연동
      • Django Admin
      • Django View & URL (2)
      • Django Template
      • Django Template & View & URL
      • Django Static
      • Django form
    • Advanced
      • Django Generic View
      • Django Automated Testing
      • Django Extenstion Template
      • Django Model Package
      • Django OpenSSL setting
    • REST framework
      • Rest API
      • Serializers
      • ViewSet
    • Error
      • 환경설정 zlib 오류발생
      • ModuleNotFoundError
    • 패키지
      • django-debug-toolbar
    • Vue.js 연동하기
  • Ruby
    • variable & input/output
    • 조건문
    • 반복문
    • Array & Hash
    • Method
    • Proc&Lamda
    • Class
  • Ruby on Rails
    • Scaffolding
    • Controller
    • Model
    • Model-M:N relation
    • Model Validation
    • 멋사 10주차 수업(Tip)
  • HTML/CSS
    • Udacity - Intro to HTML/CSS
    • Udacity - Responsive Web Design
    • Udacity - Responsive Images
    • HTML Basic
    • CSS Basic
    • HTML5 Sementic Tag
    • HTML 텍스트 관련 태그들
    • HTML5 멀티미디어
    • HTML 폼 관련 태그들
    • 텍스트 관련 스타일
    • 색상과 배경을 위한 스타일
    • 레이아웃을 위한 스타일
    • CSS 포지셔닝
    • 다재다능한 CSS3 선택자
    • CSS와 애니메이션
    • 반응형 웹이란?
  • OS(운영체제)
    • Linux
      • Daemon
      • Cron
      • 프로세스 관련 명령어
      • 텍스트 파일 명령어
  • Network
    • 네트워크 기본 개념
    • 네트워크 기본 규칙
    • 물리 계층
    • 데이터 링크 계층
    • 네트워크 계층
    • 전송 계층
    • 응용 계층
    • 네트워크 전체 흐름
    • 무선 랜
  • IT 기타지식
    • NAS란
Powered by GitBook
On this page
  • DFS (깊이 우선 탐색)
  • 백트래킹(Backtracking)
  • 탐색과정
  • 장단점
  • 구현
  • BFS (너비 우선 탐색)
  • 탐색과정
  • Queue
  • 구현
  • 시간복잡도
  • DFS vs BFS
  • 문제풀어보기
  • DFS와 BFS
  • DFS
  • flood_fill
  • n-queen

Was this helpful?

  1. Algorithm

DFS와 BFS

Previous이진탐색트리(Binary Search Tree)Next다익스트라 알고리즘(Dijkstra's Algorithm)

Last updated 3 years ago

Was this helpful?

탐색 알고리즘에 대해서 알아볼 것이다. 그래프의 탐색의 목적은 모든 정점을 1번씩 방문 하는 것이다.

DFS (깊이 우선 탐색)

깊이 우선 탐색은 한 방향으로 갈 수 있는 만큼 깊이가기때문에 깊이 우선 탐색이다. 일반적으로 DFS 탐색방법에서는 스택(stack)자료구조를 이용한다.

백트래킹(Backtracking)

탐색 과정에서 무한히 깊이가는 것을 방지하기 위해서 깊이제한(depth bound)을 둔다. depth bound에 도달할 때까지 목표(노드)가 발견되지 않으면 그 전에 탐색한 노드의 부모 노드로 되돌아온다. 이렇게 되돌아 오는 과정을 **백트래킹(Backtracking)**이라 한다.

탐색과정

최대한 깊숙히 많은것을 탐색할 때 사용하며, 스택을 사용한다.

  • 스택을 이용해 갈 수 있는 만큼 최대한 많이가고, 갈 수 없으면 이전 정점으로 돌아온다.(백트랙킹)

  • 방문한 곳은 표시를 해둔다.(check[i] )

  • 이미 방문한 곳은 건너띄고, 갈 수 있는 곳으로 간다. 스택이 비워질 때까지 계속 pop을 한다. 스택이 비어있으면 DFS탐색이 종료된다.

장단점

장점

  • 현재 경로상의 노드들만 기억하면 되므로 저장공간의 소요가 비교적 적다.

  • 목표노드가 깊은 단계에 있을 경우에 해를 빨리 구할 수 있다.

단점

  • 해가 없는 경로에 너무 깊이 빠지게 될 가능성이 잇다. 따라서 실제 경우에는 미리 지정한 임의의 깊이(depth bound)까지만 탐색하고 목표노드를 발견하지 못하면 다음 경로를 따라 탐색하는 것이 유용할 수 있다.

  • 얻어진 경로가 최단 경로가 아닐 수 있다. 목표까지의 경로가 여러개인 문제에 대해서 DFS는 목표에 도달하면 탐색을 종료하므로, 이때 찾은 경로는 최적의 경로가 아닐 수 있다.

구현

그래프가 disconnected이거나 혹은 방향 그래프라면 DFS에 의해서 모든 노드가 방문되지 않을 수 있다.

슈도코드

 DFS(G, v)
    visited[v] <- yes
    for each node adjacent to x do                                                                        
        if visited[v] = NO then
            DFS(G, u);
    end
end

인접행렬 구현

dfs(x)는 x를 방문했다는 의미이다. 재귀 호출을 이용해서 구현할 수 있다.

void dfs(int x){
    check[x] = true; //방문한 것 표시
    printf("%d ",x);
    //다음 정점 방문
    for(int i=1;i<=n;i++){
        //간선이 있고, 방문을 하지 않았을 경우
        if(a[x][i]==1 && check[i]==false) dfs(i);
    }
}
//인접행렬 백트릭킹 기법
//반복문 n^2번 실행
bool visited[101];
void dfs(int k)
{
	for(int i=0;i<=n;i++)
	    if(G[k][i] && !visited[G[k][i]])
        {
        	visited[G[k][i]]=true;
            dfs(G[k][i]);
        }
    return;
}
  • 시간복잡도 : V*O(V) = O(V^2)

인접리스트 사용

항상 있는 간선만 저장한다.

void dfs(int x){
    check[x] = true; //방문한 것 표시
    printf("%d ",x);
    //다음 정점 방문
    // a[x]는 x와 연결된 정점이다.
    for(int i=1;i<a[x].size();i++){
        int y = a[x][i];
        if(check[y]==false)dfs(y);
    }
}
//인접리스트 백트랙킹 기법
//반복문 m번실행
bool visited[101];
void dfs(int k)
{
	for(int i=0;i<G[i].size();i++)
	    if(!visited[G[k][i].to])
        {
        	visited[G[k][i].to]=true;
            dfs(G[k][i]);
        }
    return;
}
  • 모든 정점을 한번씩 거치고 모든 간선을 한번씩 검사하게 된다.

  • 시간복잡도 O(V+E)

BFS (너비 우선 탐색)

현재 정점에서 깊이가 1인 정점을 모두 탐색한 뒤 깊이를 늘려가는 방식이다. 너비우선탐색은 백트랙을 하지 않는다. 대신에 현재 정점에서 깊이가 1인 정점을 모두 방문해야하므로 **큐(queue)**라는 FIFO(First In First Out)자료구조를 활용해 현재 정점에서 깊이가 1 더 깊은 모든 정점을 순차적으로 큐에 저장해 탐색에 활용한다.

std::queue()를 활용하는 방법을 익힐 필요가 있다.

BFS를 하면서 각 노드에 대해서 최단 경로의 길이를 구할 수 있다.

탐색과정

  • L0 = {s}, s는 출발 노드

  • L1 = L0의 모든 이웃 노드들

  • L2 = L1에서 모든 이웃들 중 L0에 속하지 않는 노드들

  • ...

  • LN = Ln에서 모든 이웃들 중 Ln-1에 속하지 않는 노드들

다음과 같은 순서로 방문하는 방법이다.

Queue

최대한 넓게 가는길을 탐색할 때 사용하며, 큐를 사용한다. 큐를 이용해서 지금 위치에서 갈 수 있는 것을 모두 큐에 넣는 방식이다.

  • BFS는 큐에 넣을 때 방문했다고 체크(check[i])해야한다.

    • 큐에서 pop한 노드들 중에서 방문하지 않은 모든 이웃 노드를 큐에 넣으면서 방문했다고 체크해준다.

    • Queue가 빌때까지 진행해준다.

구현

그래프가 disconnected이거나 혹은 방향 그래프라면 BFS에 의해서 모든 노드가 방문되지 않을 수 있다.

슈도코드

BFS(G, s)// 그래프 G와 출발 노드 s
    Q <- ø; // 큐를 하나 생성
    Enqueue(Q,s);
    while Q!=ø do
        u <- Dequeue(Q)
        for each v adjacent to u do                                                                     
            if v is unvisited then
                mark v is visited;
                Enqueue(Q,v);
            end;
        end;
    end;
 

인접 행렬

queue<int> q;
check[1]= true;
q.push(1);
while(!q.empty()){
    int x = q.front;
    q.pop();
    printf("%d ",x);
    //다음 정점을 찾기
    for(int i=1;i<=n;i++){
        if(a[x][i]==1&&check[i]==false){
            check[i]=true;
            q.push(i);
        }
    }
}
//인접행렬
bool visited[101];

void bfs(int k)
{
	std::queue<int> Q;
    Q.push(k), visited[k]=1;
    while(!Q.empty())
    {
    	int current = Q.front();Q.pop();
        for(int i=0;i<G[current].size();i++)
        	if(G[current][i]&&!vistited[G[current][i]])
            {
            	visited[G[current][i]]=1;
                Q.push(G[current][i]);
            }
    }
}

전체 탐색하는데 있어서 반복문을 n^2번 실행하게된다.

  • 시간복잡도 O(V^2)

인접 리스트

queue<int> q;
check[1]= true;
q.push(1);
while(!q.empty()){
    int x = q.front;
    q.pop();
    printf("%d ",x);
    //다음 정점을 찾기
    for(int i=1;i<a[x].size;i++){
        int y = a[x][i];
        if(check[y]==false){
            check[y]=true;
            q.push(i);
        }
    }
}
//인접리스트에 저장했을 경우
#include <queue>
bool visited[101];

void bfs(int k)
{
	std::queue<int> Q;
    Q.push(k), visited[k]=1;
    while(!Q.empty())
    {
    	int current = Q.front();Q.pop();
        for(int i=0;i<G[current].size();i++)
        	if(!vistited[G[current][i]])
            {
            	visited[G[current][i]]=1;
                Q.push(G[current][i]);
            }
    }
}

전체를 탐색하는 데 있어서 반복문을 m번 실행하게 된다.

최단 경로

  • 입력 : 방향 혹은 무방향 그래프 G(V,E), 그리고 출발노드 s

  • 출력 : 모든 노드 v에 대해서

    • d[v] = s로부터 v까지의 최단 경로의 길이(엣지의 수)

    • π[v] = s로부터 v까지의 최단 경로상에서 v의 직전 노드(predecessor)

BFS(G, s)// 그래프 G와 출발 노드 s
    Q <- ø;
    d[v]<-0;
    π[v]<-null;
    Enqueue(Q,s);
    while Q!=ø do
        u <- Dequeue(Q)
        for each v adjacent to u do                                                                      
            if v is unvisited then //일반적으로 방문하지 않은 것은 -1로 넣어두고 구한다.
                mark v is visited;
                d[v]<-d[u]+1;
                π[v]<-u;
                Enqueue(Q,v);
            end;
        end;
    end;
 
// 최단경로 출력
PRINT-PATH(G,s,v)
    if v=s then
        print s;
    else if π[v] = null then
        print "no path from s to v exists";                                                               
    else
        PRINT-PATH(G,s,π[v]);
        print v;
    end.

시간복잡도

  • 시간복잡도 O(V+E)

DFS vs BFS

DFS
BFS

동작 원리

스택

큐

구현 방법

재귀

큐 자료구조 이용

문제풀어보기

그래프를 DFS로 탐색한 결과와 BFS로 탐색한 결과를 출력하는 프로그램을 작성하시오. 단, 방문할 수 있는 정점이 여러 개인 경우에는 정점 번호가 작은 것을 먼저 방문하고, 더 이상 방문할 수 있는 점이 없는 경우 종료한다. 정점 번호는 1번부터 N번까지이다.

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>

using namespace std;
vector<int> a[1001];
bool check[1001];


void dfs(int node) {
    check[node] = true;
    printf("%d ",node);
    for (int i=0; i<a[node].size(); i++) {
        int next = a[node][i];
        if (check[next] == false) {
            dfs(next);
        }
    }
}

void bfs(int start) {
    queue<int> q;
    //memset은 메모리를 초기화 하는 함수
    //1번 파라미터는 값을 복사할 곳이고, 2번 파라미터는 초기화할 값, 마지막은 얼마만큼의 메모리를 초기화 할 것인지 하는 크기이다.
    memset(check,false,sizeof(check));
    check[start] = true;
    q.push(start);
    while (!q.empty()) {
        int node = q.front();
        q.pop();
        printf("%d ",node);
        for (int i=0; i<a[node].size(); i++) {
            int next = a[node][i];
            if (check[next] == false) {
                check[next] = true;
                q.push(next);
            }
        }
    }
}
int main() {
    int n, m, start;
    scanf("%d %d %d",&n,&m,&start);
    for (int i=0; i<m; i++) {
        int u,v;
        scanf("%d %d",&u,&v);
        a[u].push_back(v);
        a[v].push_back(u);
    }
    for (int i=1; i<=n; i++) {
        sort(a[i].begin(), a[i].end());
    }
    dfs(start);
    puts("");
    bfs(start);
    puts("");
    return 0;
}

DFS

flood_fill

지뢰찾기, 뿌요뿌요 등 게임에서 많이 활용되는 알고리즘. 재귀함수를 이용해 깊이우선탐색을 구현한다. 하지만 재귀의 깊이가 너무 커지면 runtime error가 발생할 수 있다. 깊이가 너무 크다고 판단되면 너비우선탐색으로 처리하거나 재귀대신 스택을 이용한다.

dfs함수 부분의 4방향 탐색을 dx,dy를 이용해 작성할 수 있다.

int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};

void dfs(int a, int b, int c)
{
	A[a][b]=c;
    for(int i=0;i<4;i++)
    	if(safe(a+dx[i],b+dy[i])&&A[a+dx[i]][b+dy[i]]==1)
        	dfs(a+dx[i],b+dy[i],c);
}

n-queen

n*n체스 보드판에 n개의 queen을 서로 공격하지 못하도록 배치하는 방법을 찾아내는 문제. 대각선 검사하면서 가야하는 알고리즘에 유용하다.

  • 퀸은 8방향으로 모두 공격할 수 있다.

    1. 첫 번째 행, 첫 번째 열에 퀸을 놓는다.

    2. 다음 행에서 가능한 가장 왼쪽 열에 퀸을 놓는다.

    3. n번째 열에 더 이상 퀸을 놓을 수 없다면 백트랙한다.

    4. 마지막 행에 퀸을 놓으면 하나의 해를 구한 것이다.

    5. 모든 경우를 조사할 때까지 백트래킹해가며 해들을 구한다.

깊이우선탐색을 하며 해를 구할 때마다 카운트해 원하는 해를 구할 수 있다. 열과 대각선만 검사하면 된다. 대각선은 행+열 위치에 체크해 기울기가 증가하는 대각선 상에 퀸을 놓을 수 있는지 없는지 확인한다. 기울기가 감소하는 대각선은 행과 열의 차가 일정하다. n+(행-열)의 위치에 체크. 백트랙 시에 가장 중요한 점은 체크배열에 기록해 두었던 체크를 모두 해제해야한다.

DFS와 BFS