알고리즘/알고리즘(C,C++)

[그래프]DFS - Deapth First Search 깊이우선 탐색

산을좋아한라쯔 2016. 4. 14. 19:29
반응형

그래프에서는 크게 두 가지 탐색법이 존재한다. 깊이우선과 너비우선 (DFS and WFS)


탐색의 목적은 '어떤 Vertex가 있을까?'하는 'Find'가 아닌, 그래프내에서 모든 Vertex를 Edge를 따라서 '순회'하는데 있다. 즉, 빠짐없이 순회하면서 그 Vertex와 Edge로부터 정보를 얻어서 무언가를 하는데 그 목적이 있다.


깊이우선은 스택(Stack)과 재귀호출을 이용해서, 너비우선은 큐(Queue)를 이용해서 구현된다.

먼저 깊이우선부터 알아보자.


깊이우선 탐색 (DFS. Depth First Search)


핵심

  - 모든 점에 대해 인접리스트 생성 : vector<vector<int>> adj

  - 모든 점에 대해 방문여부 관리 : vector<bool> visited

  - 처음에 모든 점의 방문여부를 false로 초기화하고, 모든 점에 대해서 dfs함수 호출

  - dfs()에서는, 

    . 현재의 점을 방문한 것으로 세팅: visited[u] = true

    . 현재 점과 연결된 모든 점에 대해, 만약 방문하지  않았던 점이면, dfs() 호출 (재귀적)


코드

vector<vector<int>> adj;

vector<bool> visited;

 

void dfs(int u){

         visited[u] = true;

 

         //연결된 모든 점들에 대해

         for (int i = 0; i < adj[u].size(); ++i){

                  int v = adj[u][i];

                  if (!visited[v]) dfs(v);

         }

}

 

void visitAll(){

         visited = vector<bool>(adj.size(),false);

         for (int i = 0; i < adj.size(); ++i){

                  if (!visited[i])  dfs(i);

         }

}


int main(void){

         freopen("dfs.txt", "r", stdin);

         setbuf(stdout, NULL);

 

         int V, E;

         cin >> V;         cin >> E;

 

         adj = vector<vector<int>>(V+1);

         int u, v;

         for (int i = 0; i < E; ++i){

                  cin >> u >> v;

                  adj[u].push_back(v);

         }       

         visitAll();

         return 0;

}

      

시간복잡도 고려

- 인접리스트로 구현한 경우 O(V + E)

- 행렬로 구현한 경우 O(V2)


문제 유형들 - 깊이우선탐색으로 풀 수 있는 

1) 임의의 두 점 a,b가 연결되어 있는가? (중간에 다른 점을 거쳐서라도)

   --> dfs(u)를 수행한 후, visited[v] 값을 확인하면 됨. 만약 visited[v]==false이면 연결안됨

2) 그래프가 몇 개의 컴퍼넌트(단락된 그래프 그룹)로 구성되었는가?

   --> visitAll()에서 dfs()가 몇 번 호출되는 지 세어보면 됨

3)작업간 의존관계가 있는 그래프에서의 위상정렬(totplogical sort): 의존관계 고려한 작업순서대로 정렬

   --> dfs()가 종료되기 직전에, 해당 정점을 vector에 저장해 뒀다가, 탐색이 모두 끝난 후 해당 vector내용을 거꾸로하면 소팅된 것임.



Reference

1. 구종만. 프로그래밍 대회에서 배우는 알고리즘 문제해결 전략. 인사이트. 


-끝-

반응형

'알고리즘 > 알고리즘(C,C++)' 카테고리의 다른 글

[그래프]DFS - 오일러 서킷  (0) 2016.04.16
[그래프]DFS - 위상 정렬  (0) 2016.04.15
[그래프]기본  (0) 2016.04.14
[비트 연산]에라토스테스 체  (0) 2016.04.14
[비트 연산] 기본  (0) 2016.04.14