1. ๊ธฐ๋ณธ ๊ฐ๋ ๐งช
1. ์ ์ฅ ํธ๋ฆฌ (Spanning Tree)
n๊ฐ์ ์ ์ ์ ๊ฐ์ง๋ ๊ทธ๋ํ์์ n๊ฐ์ ์ ์ ์ ๋ชจ๋ ์ฐ๊ฒฐํ ์ ์๋ n-1๊ฐ์ ๊ฐ์ ์ผ๋ก ์ด๋ฃจ์ด์ง ํธ๋ฆฌ
(๊ฐ์ ์ n-1๊ฐ ์ด์์ผ ์ ์๋ค.)
๋ฌผ๋ก n-1๊ฐ ์ด์์ ๊ฐ์ ์ ๊ฐ์ ธ๋ ์ ์ฅ ํธ๋ฆฌ๊ฐ ๋ ์ ์๋ค.
2. ์ต์ ์ ์ฅ ํธ๋ฆฌ(Minimum Spanning Tree)
๋ฌดํฅ ๊ฐ์ค์น ๊ทธ๋ํ์์ ๊ฐ์ค์น์ ํฉ์ด ๊ฐ์ฅ ์์ ์ ์ฅ ํธ๋ฆฌ๋ฅผ ์ต์ ์ ์ฅ ํธ๋ฆฌ๋ผ๊ณ ํ๋ค.
2. KRUSKAL ์๊ณ ๋ฆฌ์ฆ ๐งซ
1. ๊ธฐ๋ณธ๊ฐ๋
๊ทธ๋ฆฌ๋ ๋ฐฉ์์ ์ด์ฉํ์ฌ ์ต์ ์ ์ฅ ํธ๋ฆฌ๋ฅผ ์ฐพ๋ ๋ฐฉ์
๊ทธ๋ฆฌ๋ํ ๋ฐฉ์ ์์ฒด๊ฐ ํญ์ ์ต์ ์ ํด๋ต์ ์ ๊ณตํ๋ค๋ ๋ณด์ฅ์ ์์ง๋ง, KRUSKAL ์๊ณ ๋ฆฌ์ฆ์์๋ ์ต์ ์ ํด๋ต์ ์ ๊ณตํ๋ ๊ฒ์ผ๋ก ์ฆ๋ช
๋์ด์๋ค.
2. ๋์ ๋ฐฉ์
- ๋ชจ๋ ๊ฐ์ ๋ค์ ๊ฐ์ค์น์ ๋ฐ๋ผ ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌํ๋ค.
- ๊ฐ์ค์น๊ฐ ๋ฎ์ ๊ฐ์ ๋ค์ ์ ํํ์ฌ ํธ๋ฆฌ๋ฅผ ๋ง๋ ๋ค.
์ด๋, ์ฌ์ดํด์ ๋ง๋๋ ๊ฐ์ ์ ์ ์ธํ๋ค.
์ฌ์ดํด์ ์์ฑ ์ฌ๋ถ๋ 'union-find ์๊ณ ๋ฆฌ์ฆ'์ ๊ฐ๋ ์ ํ์ฉํ๋ค. - ๋ชจ๋ ์ ์ ์ ํฌํจ('์ ์ - 1'๊ฐ์ ๊ฐ์ ์ ์ ํํ ๊ฒฝ์ฐ) ํ ๋๊น์ง 2๋ฒ์ ์งํํ๋ค.
3. ๊ตฌํ (JAVA) ๐งฌ
์์ ์์๋ฅผ ํ ์คํธ ์ผ์ด์ค๋ก ์๊ฐํ์.
๋จผ์ ์ ์ ์ ๊ฐ์(vertexNum)์ ๊ฐ์ ์ ๊ฐ์(edgeNum)๋ฅผ ๋ฐ์์จ๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฐ์ ์ ๊ฐ์๋งํผ ๊ฐ์ ์ ์ ๋ณด(์ถ๋ฐ์ง, ๋์ฐฉ์ง, ๊ฐ์ ์ ๊ฐ์ค์น)๋ฅผ ๊ฐ์ ธ์จ๋ค. 'a, b, c, d, e, f, g'๋ '0, 1, 2, 3, 4, 5, 6'์ด๋ผ๊ณ ํ์.
์๋๋ ์ ๋ ฅ ์ ๋ณด์ ๊ตฌํ ์ฝ๋์ด๋ค.
7 9
0 1 29
1 2 16
2 3 12
3 4 22
4 5 27
5 0 10
6 1 15
6 3 18
6 4 25
public class Main {
static int vertexNum, edgeNum;
static Edge[] edges;
static int[] parents;
static class Edge implements Comparable<Edge> {
public int from;
public int to;
public int weight;
public Edge(int from, int to, int weight) {
super();
this.from = from;
this.to = to;
this.weight = weight;
}
@Override
public int compareTo(Edge o) {
return Integer.compare(this.weight, o.weight);
}
}
static void makeSet() {
parents = new int[vertexNum];
for(int i = 0; i < vertexNum; i++) {
parents[i] = i;
}
}
static int findSet(int a) {
if(parents[a] == a) {
return a;
}
else {
return parents[a] = findSet(parents[a]);
}
}
static boolean union(int a, int b) {
int aRoot = findSet(a);
int bRoot = findSet(b);
if(aRoot == bRoot) {
return false;
}
parents[aRoot] = bRoot;
return true;
}
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(in.readLine(), " ");
vertexNum = Integer.parseInt(st.nextToken());
edgeNum = Integer.parseInt(st.nextToken());
edges = new Edge[edgeNum];
for(int i = 0; i < edgeNum; i++) {
st = new StringTokenizer(in.readLine(), " ");
edges[i] = new Edge(Integer.parseInt(st.nextToken()) // ์ถ๋ฐ edge
, Integer.parseInt(st.nextToken()) // ๋์ฐฉ edge
, Integer.parseInt(st.nextToken())); // ๊ฐ์ค์น
}
// 1. ๊ฐ์ ๋ค์ ๊ฐ์ค์น์ ๋ฐ๋ผ ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌํ๋ค.
Arrays.sort(edges);
makeSet();
int mstWeight = 0;
int edgeCount = 0;
// 2. ๊ฐ์ค์น๊ฐ ๋ฎ์ ๊ฐ์ ์ ๋จผ์ ์ ํํ์ฌ ํธ๋ฆฌ๋ฅผ ๋ง๋ค์ด ๋๊ฐ๋ค.
for(Edge edge : edges) {
if(union(edge.from, edge.to)) { // ์ฌ์ดํด์ ๋ง๋ค์ง ์๋ ๊ฒฝ์ฐ
mstWeight += edge.weight;
// 3. ๋ชจ๋ ์ ์ ์ ํฌํจํ๋ ๊ฒฝ์ฐ ('์ ์ - 1'์ ๊ฐ์ ์ ์ ํํ ๊ฒฝ์ฐ)์ ๋น ์ ธ๋์จ๋ค.
if(++edgeCount == vertexNum - 1) {
break;
}
}
}
System.out.println(mstWeight);
}
}
4. ์๊ฐ๋ณต์ก๋ ๐ฌ
KRUSKAL ์๊ณ ๋ฆฌ์ฆ์ ์๊ฐ๋ณต์ก๋๋ ๊ฐ์ ๋ค์ ๊ฐ์ค์น์ ๋ฐ๋ผ ์ ๋ ฌํ๋ ๊ฒ์ ์ํด ๊ฒฐ์ ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ ๊ณ ๋ คํ์์ ๋, KRUSKAL์๊ณ ๋ฆฌ์ฆ์ ์๊ฐ ๋ณต์ก๋๋ O(N logN)์ด๋ค.
๊ทธ๋ฌ๋ฏ๋ก ๊ฐ์ ์ด ๋ง์ ๊ฒฝ์ฐ ๋ค๋ฅธ ๋ฐฉ์(PRIM ์๊ณ ๋ฆฌ์ฆ)์ ๊ณ ๋ คํด์ผ ํ๋ค.
'๐ ์๊ณ ๋ฆฌ์ฆ > ์ต์์ ์ฅํธ๋ฆฌ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
PRIM ์๊ณ ๋ฆฌ์ฆ (0) | 2023.03.01 |
---|