๐ ๊ณต๋ถํ๋ ์ง์ง์ํ์นด๋ ์ฒ์์ด์ง?
[์ด๊ฒ์ด ์ฝ๋ฉ ํ ์คํธ๋ค with Python]_35_ํฌ๋ฃจ์ค์นผ ์๊ณ ๋ฆฌ์ฆ ๋ณธ๋ฌธ
[์ด๊ฒ์ด ์ฝ๋ฉ ํ ์คํธ๋ค with Python]_35_ํฌ๋ฃจ์ค์นผ ์๊ณ ๋ฆฌ์ฆ
์ง์ง์ํ์นด 2022. 2. 13. 00:35220213 ์์ฑ
<๋ณธ ๋ธ๋ก๊ทธ๋ ใ์ด๊ฒ์ด ์ทจ์ ์ ์ํ ์ฝ๋ฉ ํ ์คํธ๋คใ ์ youtube๋ฅผ ์ฐธ๊ณ ํด์ ๊ณต๋ถํ๋ฉฐ ์์ฑํ์์ต๋๋ค>
https://www.youtube.com/watch?v=Gj7s-Nrt1xE&list=PLVsNizTWUw7H9_of5YCB0FmsSc-K44y81&index=35
1. ์ ์ฅํธ๋ฆฌ
: ๊ทธ๋ํ์์ ๋ชจ๋ ๋ ธ๋๋ฅผ ํฌํจํ๋ฉด์ ์ฌ์ดํด์ด ์กด์ฌํ์ง ์๋ ๋ถ๋ถ ๊ทธ๋ํ
: ๋ชจ๋ ๋ ธ๋๊ฐ ํฌํจ๋์ด ์๋ก ์ฐ๊ฒฐ๋๋ฉด์ ์ฌ์ดํด์ด ์กด์ฌํ์ง ์๋๋ค๋ ์กฐ๊ฑด์ ํธ๋ฆฌ์ผ ใ ฃ์กฐ๊ฑด!
2. ์ต์ ์ ์ฅ ํธ๋ฆฌ
: ์ต์ํ์ ๋น์ฉ์ผ๋ก ๊ตฌ์ฑ๋๋ ์ ์ฅ ํธ๋ฆฌ ์ฐพ๊ธฐ!
ex) N๊ฐ์ ๋์๊ฐ ์กด์ฌํ๋ ์ํฉ์์ ๋ ๋์ ์ฌ์ด์ ๋๋ก๋ฅผ ๋์ ์ ์ฒด ๋์๊ฐ ์๋ก ์ฐ๊ฒฐ๋ ์ ์๊ฒ ๋๋ก๋ฅผ ์ค์น
๋ ๋์ A, B ์ ํํ์ ๋ A์์ B๋ก ์ด๋ํ๋ ๊ฒฝ๋ก๊ฐ ๋ฐ๋์ ์กด์ฌํ๋๋ก ๋๋ก ์ค์น
3. ํฌ๋ฃจ์ค์นผ ์๊ณ ๋ฆฌ์ฆ
: ๋ํ์ ์ธ ์ต์ ์ ์ฅ ํธ๋ฆฌ
: ๊ทธ๋ฆฌ๋ ์๊ณ ๋ฆฌ์ฆ
1) ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋น์ฉ์ ๋ฐ๋ผ ์ค๋ฆ์ฐจ์ ์ ๋ ฌ
2) ๊ฐ์ ์ ํ๋์ฉ ํ์ธํ๋ฉฐ ํ์ฌ์ ๊ฐ์ ์ด ์ฌ์ดํด์ ๋ฐ์ํ๋์ง ํ์ธ
- ์ฌ์ดํด ๋ฐ์ํ์ง ์๋ ๊ฒฝ์ฐ ์ต์ ์ ์ฅ ํธ๋ฆฌ์ ํฌํจ
- ์ฌ์ดํด ๋ฐ์ํ๋ ๊ฒฝ์ฐ ์ต์ ์ ์ฅ ํธ๋ฆฌ์ ํฌํจ
3) ๋ชจ๋ ๊ฐ์ ์ ๋ํ์ฌ 2๋ฒ ๊ณผ์ ๋ฐ๋ณต
=> ์ต์ ์ ์ฅ ํธ๋ฆฌ์ ํฌํจ๋์ด ์๋ ๊ฐ์ ์ ๋น์ฉ๋ง ๋ชจ๋ ๋ํ๋ฉด, ๊ทธ ๊ฐ์ด ์ต์ข ๋น์ฉ์ ํด๋น!
- python
# ํน์ ์์๊ฐ ์ํ ์งํฉ์ ์ฐพ๊ธฐ
def find_parent(parent, x):
# ๋ฃจํธ ๋
ธ๋๊ฐ ์๋๋ผ๋ฉด, ๋ฃจํธ ๋
ธ๋๋ฅผ ์ฐพ์ ๋๊น์ง ์ฌ๊ท์ ์ผ๋ก ํธ์ถ
if parent[x] != x:
parent[x] = find_parent(parent, parent[x])
return parent[x]
# ๋ ์์๊ฐ ์ํ ์งํฉ์ ํฉ์น๊ธฐ
def union_parent(parent, a, b):
a = find_parent(parent, a)
b = find_parent(parent, b)
if a < b:
parent[b] = a
else:
parent[a] = b
# ๋
ธ๋์ ๊ฐ์์ ๊ฐ์ (Union ์ฐ์ฐ)์ ๊ฐ์ ์
๋ ฅ ๋ฐ๊ธฐ
v, e = map(int, input().split())
parent = [0] * (v + 1) # ๋ถ๋ชจ ํ
์ด๋ธ ์ด๊ธฐํํ๊ธฐ
# ๋ชจ๋ ๊ฐ์ ์ ๋ด์ ๋ฆฌ์คํธ์, ์ต์ข
๋น์ฉ์ ๋ด์ ๋ณ์
edges = []
result = 0
# ๋ถ๋ชจ ํ
์ด๋ธ์์์, ๋ถ๋ชจ๋ฅผ ์๊ธฐ ์์ ์ผ๋ก ์ด๊ธฐํ
for i in range(1, v + 1):
parent[i] = i
# ๋ชจ๋ ๊ฐ์ ์ ๋ํ ์ ๋ณด๋ฅผ ์
๋ ฅ ๋ฐ๊ธฐ
for _ in range(e):
a, b, cost = map(int, input().split())
# ๋น์ฉ์์ผ๋ก ์ ๋ ฌํ๊ธฐ ์ํด์ ํํ์ ์ฒซ ๋ฒ์งธ ์์๋ฅผ ๋น์ฉ์ผ๋ก ์ค์
edges.append((cost, a, b))
# ๊ฐ์ ์ ๋น์ฉ์์ผ๋ก ์ ๋ ฌ
edges.sort()
# ๊ฐ์ ์ ํ๋์ฉ ํ์ธํ๋ฉฐ
for edge in edges:
cost, a, b = edge
# ์ฌ์ดํด์ด ๋ฐ์ํ์ง ์๋ ๊ฒฝ์ฐ์๋ง ์งํฉ์ ํฌํจ
if find_parent(parent, a) != find_parent(parent, b):
union_parent(parent, a, b)
result += cost
print(result)
- c++
#include <bits/stdc++.h>
using namespace std;
// ๋
ธ๋์ ๊ฐ์(V)์ ๊ฐ์ (Union ์ฐ์ฐ)์ ๊ฐ์(E)
// ๋
ธ๋์ ๊ฐ์๋ ์ต๋ 100,000๊ฐ๋ผ๊ณ ๊ฐ์
int v, e;
int parent[100001]; // ๋ถ๋ชจ ํ
์ด๋ธ ์ด๊ธฐํ
// ๋ชจ๋ ๊ฐ์ ์ ๋ด์ ๋ฆฌ์คํธ์, ์ต์ข
๋น์ฉ์ ๋ด์ ๋ณ์
vector<pair<int, pair<int, int> > > edges;
int result = 0;
// ํน์ ์์๊ฐ ์ํ ์งํฉ์ ์ฐพ๊ธฐ
int findParent(int x) {
// ๋ฃจํธ ๋
ธ๋๊ฐ ์๋๋ผ๋ฉด, ๋ฃจํธ ๋
ธ๋๋ฅผ ์ฐพ์ ๋๊น์ง ์ฌ๊ท์ ์ผ๋ก ํธ์ถ
if (x == parent[x]) return x;
return parent[x] = findParent(parent[x]);
}
// ๋ ์์๊ฐ ์ํ ์งํฉ์ ํฉ์น๊ธฐ
void unionParent(int a, int b) {
a = findParent(a);
b = findParent(b);
if (a < b) parent[b] = a;
else parent[a] = b;
}
int main(void) {
cin >> v >> e;
// ๋ถ๋ชจ ํ
์ด๋ธ์์์, ๋ถ๋ชจ๋ฅผ ์๊ธฐ ์์ ์ผ๋ก ์ด๊ธฐํ
for (int i = 1; i <= v; i++) {
parent[i] = i;
}
// ๋ชจ๋ ๊ฐ์ ์ ๋ํ ์ ๋ณด๋ฅผ ์
๋ ฅ ๋ฐ๊ธฐ
for (int i = 0; i < e; i++) {
int a, b, cost;
cin >> a >> b >> cost;
// ๋น์ฉ์์ผ๋ก ์ ๋ ฌํ๊ธฐ ์ํด์ ํํ์ ์ฒซ ๋ฒ์งธ ์์๋ฅผ ๋น์ฉ์ผ๋ก ์ค์
edges.push_back({cost, {a, b}});
}
// ๊ฐ์ ์ ๋น์ฉ์์ผ๋ก ์ ๋ ฌ
sort(edges.begin(), edges.end());
// ๊ฐ์ ์ ํ๋์ฉ ํ์ธํ๋ฉฐ
for (int i = 0; i < edges.size(); i++) {
int cost = edges[i].first;
int a = edges[i].second.first;
int b = edges[i].second.second;
// ์ฌ์ดํด์ด ๋ฐ์ํ์ง ์๋ ๊ฒฝ์ฐ์๋ง ์งํฉ์ ํฌํจ
if (findParent(a) != findParent(b)) {
unionParent(a, b);
result += cost;
}
}
cout << result << '\n';
}
- java
import java.util.*;
class Edge implements Comparable<Edge> {
private int distance;
private int nodeA;
private int nodeB;
public Edge(int distance, int nodeA, int nodeB) {
this.distance = distance;
this.nodeA = nodeA;
this.nodeB = nodeB;
}
public int getDistance() {
return this.distance;
}
public int getNodeA() {
return this.nodeA;
}
public int getNodeB() {
return this.nodeB;
}
// ๊ฑฐ๋ฆฌ(๋น์ฉ)๊ฐ ์งง์ ๊ฒ์ด ๋์ ์ฐ์ ์์๋ฅผ ๊ฐ์ง๋๋ก ์ค์
@Override
public int compareTo(Edge other) {
if (this.distance < other.distance) {
return -1;
}
return 1;
}
}
public class Main {
// ๋
ธ๋์ ๊ฐ์(V)์ ๊ฐ์ (Union ์ฐ์ฐ)์ ๊ฐ์(E)
// ๋
ธ๋์ ๊ฐ์๋ ์ต๋ 100,000๊ฐ๋ผ๊ณ ๊ฐ์
public static int v, e;
public static int[] parent = new int[100001]; // ๋ถ๋ชจ ํ
์ด๋ธ ์ด๊ธฐํํ๊ธฐ
// ๋ชจ๋ ๊ฐ์ ์ ๋ด์ ๋ฆฌ์คํธ์, ์ต์ข
๋น์ฉ์ ๋ด์ ๋ณ์
public static ArrayList<Edge> edges = new ArrayList<>();
public static int result = 0;
// ํน์ ์์๊ฐ ์ํ ์งํฉ์ ์ฐพ๊ธฐ
public static int findParent(int x) {
// ๋ฃจํธ ๋
ธ๋๊ฐ ์๋๋ผ๋ฉด, ๋ฃจํธ ๋
ธ๋๋ฅผ ์ฐพ์ ๋๊น์ง ์ฌ๊ท์ ์ผ๋ก ํธ์ถ
if (x == parent[x]) return x;
return parent[x] = findParent(parent[x]);
}
// ๋ ์์๊ฐ ์ํ ์งํฉ์ ํฉ์น๊ธฐ
public static void unionParent(int a, int b) {
a = findParent(a);
b = findParent(b);
if (a < b) parent[b] = a;
else parent[a] = b;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
v = sc.nextInt();
e = sc.nextInt();
// ๋ถ๋ชจ ํ
์ด๋ธ์์์, ๋ถ๋ชจ๋ฅผ ์๊ธฐ ์์ ์ผ๋ก ์ด๊ธฐํ
for (int i = 1; i <= v; i++) {
parent[i] = i;
}
// ๋ชจ๋ ๊ฐ์ ์ ๋ํ ์ ๋ณด๋ฅผ ์
๋ ฅ ๋ฐ๊ธฐ
for (int i = 0; i < e; i++) {
int a = sc.nextInt();
int b = sc.nextInt();
int cost = sc.nextInt();
edges.add(new Edge(cost, a, b));
}
// ๊ฐ์ ์ ๋น์ฉ์์ผ๋ก ์ ๋ ฌ
Collections.sort(edges);
// ๊ฐ์ ์ ํ๋์ฉ ํ์ธํ๋ฉฐ
for (int i = 0; i < edges.size(); i++) {
int cost = edges.get(i).getDistance();
int a = edges.get(i).getNodeA();
int b = edges.get(i).getNodeB();
// ์ฌ์ดํด์ด ๋ฐ์ํ์ง ์๋ ๊ฒฝ์ฐ์๋ง ์งํฉ์ ํฌํจ
if (findParent(a) != findParent(b)) {
unionParent(a, b);
result += cost;
}
}
System.out.println(result);
}
}
4. ์ฑ๋ฅ ๋ถ์
: ๊ฐ์ ์ ๊ฐ์๊ฐ E๊ฐ ์ผ ๋ O(ElogE) ์๊ฐ๋ณต์ก๋
: ๊ฐ์ฅ ๋ง์ ์๊ฐ ์๊ตฌ ๋ถ๋ถ์ ๊ฐ์ ์ ์ ๋ ฌ ์ํํ๋ ๋ถ๋ถ!