가장 적은 비용으로 모든 노드를 연결하기 위해 사용하는 알고리즘이다.
프림, 크루스칼이 있는데 둘중 하나만 알아도 된다 해서 일단은 그러는 중이다.
싸이클이 생기는지 알기 위해서 유니온 파인드를 활용한다.
https://www.acmicpc.net/problem/1197
1197번: 최소 스패닝 트리
첫째 줄에 정점의 개수 V(1 ≤ V ≤ 10,000)와 간선의 개수 E(1 ≤ E ≤ 100,000)가 주어진다. 다음 E개의 줄에는 각 간선에 대한 정보를 나타내는 세 정수 A, B, C가 주어진다. 이는 A번 정점과 B번 정점이 �
www.acmicpc.net
베이스는 이 문제이다.
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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | #include <iostream> #define pii pair<int, int> using namespace std; class Edge { public : int start, end, dist; }; Edge edge[100000]; int e_size = 0; int parent[10001]; void q_sort(int left, int right) { if (left >= right) return; swap(edge[left], edge[(left + right) / 2]); int i = left + 1; int j = right; int pivot = left; while (1) { while (i <= right && edge[i].dist < edge[pivot].dist) i++; while (j >= left + 1 && edge[j].dist > edge[pivot].dist) j--; if (i < j) swap(edge[i++], edge[j--]); else break; } swap(edge[pivot], edge[j]); q_sort(left, j - 1); q_sort(j + 1, right); } int find(int node) { if (parent[node] == node) return node; return parent[node] = find(parent[node]); } int merge(Edge e) { int a = find(e.start); int b = find(e.end); if (a == b) return 0; else { parent[a] = b; return e.dist; } } int main() { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int v, e; cin >> v >> e; int a, b, c; for (int i = 0; i < e; i++) { cin >> a >> b >> c; edge[e_size++] = { a,b,c }; } q_sort(0, e - 1); for (int i = 1; i <= v; i++) parent[i] = i; int ans = 0; for (int i = 0; i < e_size; i++) ans += merge(edge[i]); cout << ans; } | cs |