카테고리 없음

More on Graph algorithms

fw93 2018. 6. 3. 10:34

1. 최소 스패닝 트리


1) 프림 알고리즘



현재 MST에 속해 있는 점에서 가장 작은 가중치의 엣지와 노드를 추가한다.

계속 추가해 나간다.

끗.


정당성 : 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <queue>
#include <unordered_map>
 
using namespace std;
 
int main() {
    // get inputs and make graph
    int nodes;
    int edges;
    scanf("%d %d"&nodes, &edges);
    unordered_map<intint> locator;
    vector < vector<pair<intint>>> graph(nodes, vector < pair<intint>>());
    int numbering = 0;
    for (int i = 0; i < edges; i++) {
        int from;
        int to;
        int weight;
        scanf("%d %d %d"&from, &to, &weight);
        auto it = locator.find(from);
        if (it != locator.end()) {
            from = it->second;
        }
        else {
            locator.insert(pair<intint>(from, numbering));
            from = numbering;
            numbering++;
        }
        it = locator.find(to);
        if (it != locator.end()) {
            to = it->second;
        }
        else {
            locator.insert(pair<intint>(to, numbering));
            to = numbering;
            numbering++;
        }
        graph[from].push_back(pair<intint>(to, weight));
        graph[to].push_back(pair<intint>(from, weight));
    }
 
    // do prim mst
    vector<int> included(nodes, 0);
    priority_queue < pair<intpair<intint>>vector<pair<intpair<intint>>>, greater<pair<intpair<intint>>>> queue;
    vector<pair<intint>> total;
    long long sum = 0LL;
 
    for (int k = 0; k < nodes; k++) {
        if (included[k] == 0) {
            included[k] = 1;
            for (int i = 0; i < graph[k].size(); i++) {
                queue.push(pair<intpair<intint>>(graph[k][i].second, pair<intint>(k, graph[k][i].first)));
            }
 
            // go through all candidates
            while (queue.size() != 0) {
                pair<intpair<intint>> curr = queue.top();
                queue.pop();
                if (included[curr.second.second] == 0) {
                    included[curr.second.second] = 1;
                    total.push_back(pair<intint>(curr.second.first, curr.second.second));
                    sum += curr.first;
                    for (int i = 0; i < graph[curr.second.second].size(); i++) {
                        if(included[graph[curr.second.second][i].first]==0)
                            queue.push(pair<intpair<intint>>(graph[curr.second.second][i].second, pair<intint>(curr.second.second, graph[curr.second.second][i].first)));
                    }
                }
            }
        }
    }
    cout << sum << endl;
}
cs


시간 복잡도 : O(ElogE ~ ElogV)

공간 복잡도 : O(V+E)


2. 최단 경로 알고리즘


1) 다익스트라


출발점을 0으로 두고 주변 엣지를 min heap에 저장. 가장 작은 weight부터 하나씩 확장하면서 해당 node의 값을 업데이트하고, 그 edge를 전부 min heap에 추가하면서 진행한다. node의 weight가 작아지는 경우에만 다시 업데이트한다.


2) 플로이드 - 워셜


3) 벨만 - 포드





3. Strongly connected components


[알고리즘]


DFS의 종료 순서대로 스택에 담는다.

역방향 그래프를 생성한다.

스택의 순서대로 역방향 그래프를 DFS로 순회한다.

각 DFS 조각이 SCC 조각이다.


정당성 :


코드 :  https://github.com/fw93/Personal_Projects/tree/master/School/Algorithm%20HW/HW3


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