본문 바로가기
학과공부/자료구조

Digraphs

by 유시은 2020. 12. 8.
개요

모든 간선이 directed인 그래프

 

 

Directed DFS

간선은 탐색 시점을 기준으로 discovery, back, forward, cross의 네 종류로 분류한다.

  • discovery: end vertex가 unexplored인 edge
  • back: end vertex가 ancestor인 edge
  • forward: end vertex가 descendant인 edge
  • cross: end vertex가 ancestor도 descendant도 아닌 정점인 edge

 

DAG와 위상 순서

DAG: Directed Acyclic Graph

 

위상 순서: 각 정점을 v1, v2, ..., vn이라고 할 때 모든 간선 (vi, vj)에 대해 i < j가 성립하는 순서

 

 

위상 정렬 알고리즘

시간복잡도 O(n + m)의 알고리즘이다.

TopologicalSort(Graph G):
    H = G
    n = G.numVertices()
    while not H.empty():
        v = vertex with no outdegree
        v.setLabel( n )
        n -= 1
        remove v from H

 

dfs를 이용한 구현은 다음을 참고하자.

 

#include <bits/stdc++.h>
using namespace std;

enum { UNEXPLORED, VISITED };

struct Node {
    int label, order;
    Node() { label = UNEXPLORED, order = -1; }
};

struct digraph {
    int N, M;
    vector<Node> nodes;
    vector<vector<int>> edges;

    digraph(int n) {
        N = M = n;
        nodes.resize(N);
        edges.resize(N);
    }

    void addEdge(int p, int q) { edges[p].push_back(q); }
};

void dfs(digraph& G, int cur) {
    G.nodes[cur].label = VISITED;
    for (int next : G.edges[cur]) {
        if (G.nodes[next].label == UNEXPLORED) {
            dfs(G, next);
        }
    }
    G.nodes[cur].order = G.M;
    G.M -= 1;
}
void toposort(digraph& G) {
    int N = G.N;
    vector<bool> dup(N, false);
    for (int i = 0; i < N; ++i)
        if (G.nodes[i].label == UNEXPLORED) dfs(G, i);
}

int main() {
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

    int n, m; cin >> n >> m;
    digraph G(n);
    while (m--) {
        int p, q; cin >> p >> q; p--; q--;
        G.addEdge(p, q);
    }
    toposort(G);

    for (Node& n : G.nodes) cout << n.order << " ";
}

 

'학과공부 > 자료구조' 카테고리의 다른 글

BFS와 DFS  (0) 2020.12.08
Graphs  (0) 2020.12.07
Hash Table  (0) 2020.12.07
Map & Dictionary  (0) 2020.12.07
Binary Search Tree  (0) 2020.12.04

댓글