์ต์์ ์ฅํธ๋ฆฌ๋ฅผ ๋ง๋๋ ๋ ๋ฒ์งธ ๋ฐฉ๋ฒ์ธ PRIM ์๊ณ ๋ฆฌ์ฆ์ ๋ํด์ ์์๋ณด์. (์ฒซ ๋ฒ์งธ ๋ฐฉ๋ฒ์ผ๋ก๋ KRUSKAL ์๊ณ ๋ฆฌ์ฆ์ด ์์๋ค.)
1. PRIM ์๊ณ ๋ฆฌ์ฆ ๐
1. ๊ธฐ๋ณธ ๊ฐ๋
๊ทธ๋ฆฌ๋ ๋ฐฉ์์ ์ด์ฉํ์ฌ ์ต์ ์ ์ฅ ํธ๋ฆฌ๋ฅผ ์ฐพ๋ ๋ฐฉ์
์์ ์ ์ ์์๋ถํฐ ์ถ๋ฐํ์ฌ ์ ์ฅํธ๋ฆฌ ์งํฉ์ ๋จ๊ณ์ ์ผ๋ก ๋ง๋ค์ด ๋๊ฐ๋ ๋ฐฉ์
2. ๋์ ๋ฐฉ์
- ๊ทธ๋ํ์์ ํ๋์ ์ ์ ์ ์ ํํ์ฌ ํธ๋ฆฌ๋ฅผ ๋ง๋ ๋ค.
- ํธ๋ฆฌ์ ์ฐ๊ฒฐ๋์ด ์์ง๋ง ์์ง ์ ํ๋์ง ์์ ์ ์ ๋ค ์ค์์ ๊ฐ์ ์ ๊ฐ์ค์น๊ฐ ๊ฐ์ฅ ๋ฎ์ ์ ์ ์ ํธ๋ฆฌ์ ํฌํจ์ํจ๋ค.
- ํธ๋ฆฌ๊ฐ N-1์ ๊ฐ์ ์ ๊ฐ์ง ๋๊น์ง 2๋ฒ์ ๋ฐ๋ณตํ๋ค.
2. ๊ตฌํ (JAVA) ๐คฟ
๊ตฌํ ๋ฐฉ์์ผ๋ก๋ ์๋์ 2๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค.
- ๋ฐ๋ณต๋ฌธ์ ํตํด ๋ค์ ์ ์ ์ ์ฐพ๋ ๋ฐฉ์
- PriorityQueue๋ฅผ ์ด์ฉํด ๋ค์ ์ ์ ์ ์ฐพ๋ ๋ฐฉ์
์์ ์์๋ฅผ ํตํด PRIM ์๊ณ ๋ฆฌ์ฆ์ ์์๋ณด์.('a, b, c, d, e, f, g'๋ '0, 1, 2, 3, 4, 5, 6'์ผ๋ก ๋ํ๋ธ๋ค.)
PRIM ์๊ณ ๋ฆฌ์ฆ์ ์จ์ผ ํ๋ ๊ฒฝ์ฐ๋ ๋์ฒด์ ์ผ๋ก ๊ฐ์ ์ด ๋ง์ ๊ฒฝ์ฐ์ด๋ค. ์ด๋ฐ ๊ฒฝ์ฐ์๋ ํ๋ ฌ์ ํ์์ผ๋ก ์
๋ ฅ์ด ๋ง์ด ์ฃผ์ด์ง๋ฏ๋ก ํ๋ ฌ์ ํ์์ผ๋ก ์
๋ ฅ์ ๋ฐ์๋ณด์. ๋จผ์ ์ ์ ์ ๊ฐ์(vertexNum)๋ฅผ ๋ฐ๊ณ , ๊ทธ๋ฆฌ๊ณ ๊ฐ์ค์น์ ํด๋นํ๋ 2์ฐจ์ ํ๋ ฌ์ ๋ฐ๋๋ค.
์๋๋ ์ ๋ ฅ ์ ๋ณด์ ๊ตฌํ ์ฝ๋์ด๋ค.
7
0 29 0 0 0 10 0
29 0 16 0 0 0 15
0 16 0 12 0 0 0
0 0 12 0 22 0 18
0 0 0 22 0 27 25
10 0 0 0 27 0 0
0 15 0 18 25 0 0
๋ฐฉ๋ฒ 1 - ๋ฐ๋ณต๋ฌธ์ ํตํด ๋ค์ ์ ์ ์ ์ฐพ๋ ๋ฐฉ์
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(in.readLine(), " ");
int vertexNum = Integer.parseInt(st.nextToken());
int edgeNum = Integer.parseInt(st.nextToken());
// ๊ฐ์ ์ ๊ฐ์ค์น๋ฅผ ์ ์ฅํ๋ ๋ฐฐ์ด
int[][] adjMatrix = new int[vertexNum][vertexNum];
// ์ ์ ์ ๋ฐฉ๋ฌธํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ๊ฐ์ ์ ์ต์ ๊ฐ์ค์น
int[] minWeightForVertex = new int[vertexNum];
boolean[] visited = new boolean[vertexNum];
for (int from = 0; from < vertexNum; from++) {
st = new StringTokenizer(in.readLine(), " ");
for (int to = 0; to < vertexNum; to++) {
adjMatrix[from][to] = Integer.parseInt(st.nextToken());
}
}
// ์์ง ํ์์ ํ๋ฉด์ ์ต์ ๊ฐ์ค์น๋ฅผ ์
๋ฐ์ดํธ ํ๊ธฐ ์ ์ด๋ฏ๋ก,
// ์๋์ ๊ฐ์ด ์ด๊ธฐํ
for(int i = 0; i < vertexNum; i++) {
minWeightForVertex[i] = Integer.MAX_VALUE;
}
// ๋ฐฉ๋ฌธํ ์ ์ ์ ๊ฐ์
int vertexCount = 0;
int mstWeight = 0;
// ์์ ์ ์ ์ ์๋ฌด๊ฑฐ๋ ํด๋ ๋จ
int startVertex = 0;
// ์์ ์ ์ ์ ๋ฐฉ๋ฌธํ๊ธฐ ์ํด์ ์ฌ์ฉํ ๊ฐ์ ์ ์์ผ๋ฏ๋ก
// ๊ฐ์ ์ ๊ฐ์ค์น๋ 0์ผ๋ก ์ธํ
minWeightForVertex[startVertex] = 0;
//
for(int i = 0; i < vertexNum; i++) {
// ํธ๋ฆฌ์ ์ฐ๊ฒฐ๋์ด ์์ง๋ง ์์ง ์ ํ๋์ง ์์ ์ ์ ๋ค ์ค์์
// ๊ฐ์ฅ ๋ฎ์ ๊ฐ์ ์ ๊ฐ์ค์น(minWeightForNextVertex)์
// ํด๋น ์ ์ (minVertex)์ ์ ์ฅํ๊ธฐ ์ํ ๋ณ์
int minWeightForNextVertex = Integer.MAX_VALUE;
int minVertex = startVertex;
for(int j = 0; j < vertexNum; j++) {
if(!visited[j] && minWeightForNextVertex > minWeightForVertex[j]) {
minWeightForNextVertex = minWeightForVertex[j];
minVertex = j;
}
}
// ํธ๋ฆฌ์ ์ ์ ์ ์ถ๊ฐํ๋ ๊ณผ์
visited[minVertex] = true;
mstWeight += minWeightForNextVertex;
// (์ ์ - 1)๊ฐ์ ๊ฐ์ ์ด ์๊ธด ๊ฒฝ์ฐ
if(++vertexCount == vertexNum) {
break;
}
// ์ ์ ์ด ์์ง ํธ๋ฆฌ์ ํฌํจ๋์ง ์์๊ณ
// ๊ฐ์ ์ด ์กด์ฌํ๋ ๊ฒฝ์ฐ
// ํด๋น ์ ์ ์ผ๋ก ๊ฐ ์ ์๋ ์ต์ ๊ฐ์ค์น์ ๊ฐ์ ์ ์ ํํ๋ ๊ณผ์
for(int j = 0; j < vertexNum; j++) {
if(!visited[j] && adjMatrix[minVertex][j] != 0
&& minWeightForVertex[j] > adjMatrix[minVertex][j]) {
minWeightForVertex[j] = adjMatrix[minVertex][j];
}
}
}
System.out.println(mstWeight);
}
}
๋ฐฉ๋ฒ 2 - PriorityQueue๋ฅผ ์ด์ฉํด ๋ค์ ์ ์ ์ ์ฐพ๋ ๋ฐฉ์
public class Main {
private static class Vertex implements Comparable<Vertex> {
public int idx;
public int weight;
public Vertex(int idx, int weight) {
super();
this.idx = idx;
this.weight = weight;
}
@Override
public int compareTo(Vertex o) {
return Integer.compare(this.weight, o.weight);
}
}
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(in.readLine());
int vertexNum = Integer.parseInt(st.nextToken());
// ๊ฐ์ ์ ๊ฐ์ค์น๋ฅผ ์ ์ฅํ๋ ๋ฐฐ์ด
int[][] adjMatrix = new int[vertexNum][vertexNum];
// ์ ์ ์ ๋ฐฉ๋ฌธํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ๊ฐ์ ์ ์ต์ ๊ฐ์ค์น
int[] minWeightForVertex = new int[vertexNum];
boolean[] visited = new boolean[vertexNum];
for (int from = 0; from < vertexNum; from++) {
st = new StringTokenizer(in.readLine(), " ");
for (int to = 0; to < vertexNum; to++) {
adjMatrix[from][to] = Integer.parseInt(st.nextToken());
}
}
// ์์ง ํ์์ ํ๋ฉด์ ์ต์ ๊ฐ์ค์น๋ฅผ ์
๋ฐ์ดํธ ํ๊ธฐ ์ ์ด๋ฏ๋ก,
// ์๋์ ๊ฐ์ด ์ด๊ธฐํ
for(int i = 0; i < vertexNum; i++) {
minWeightForVertex[i] = Integer.MAX_VALUE;
}
// PriorityQueue
Queue<Vertex> queue = new PriorityQueue<>();
// ์์ ์ ์ ์ ์๋ฌด๊ฑฐ๋ ํด๋ ๋จ
int startVertex = 0;
// ์์ ์ ์ ์ ๋ฐฉ๋ฌธํ๊ธฐ ์ํด์ ์ฌ์ฉํ ๊ฐ์ ์ ์์ผ๋ฏ๋ก
// ๊ฐ์ ์ ๊ฐ์ค์น๋ 0์ผ๋ก ์ธํ
queue.offer(new Vertex(startVertex, 0));
// ๋ฐฉ๋ฌธํ ์ ์ ์ ๊ฐ์
int vertexCount = 0;
int mstWeight = 0;
while(!queue.isEmpty()) {
// ๋ค์ ์ ์ ์ ํ๋ณด๋ค ์ค ๊ฐ์ ์ ๊ฐ์ค์น๊ฐ ๊ฐ์ฅ ์์ ์ ์ ์ ์ ํ
Vertex minVertex = queue.poll();
// ์ด๋ฏธ ํธ๋ฆฌ์ ํฌํจ๋ ๊ฒฝ์ฐ
if(visited[minVertex.idx]) {
continue;
}
// ํธ๋ฆฌ์ ์ ์ ์ ์ถ๊ฐํ๋ ๊ณผ์
visited[minVertex.idx] = true;
mstWeight += minVertex.weight;
// (์ ์ - 1)๊ฐ์ ๊ฐ์ ์ด ์๊ธด ๊ฒฝ์ฐ
if(++vertexCount == vertexNum) {
break;
}
// ์ ์ ์ด ์์ง ํธ๋ฆฌ์ ํฌํจ๋์ง ์์๊ณ
// ๊ฐ์ ์ด ์กด์ฌํ๋ ๊ฒฝ์ฐ
// ํด๋น ์ ์ ์ผ๋ก ๊ฐ ์ ์๋ ์ต์ ๊ฐ์ค์น์ ๊ฐ์ ์ ์ ํํ๋ ๊ณผ์
for(int i = 0; i < vertexNum; i++) {
if(!visited[i] && adjMatrix[minVertex.idx][i] != 0
&& minWeightForVertex[i] > adjMatrix[minVertex.idx][i]) {
minWeightForVertex[i] = adjMatrix[minVertex.idx][i];
queue.offer(new Vertex(i, adjMatrix[minVertex.idx][i]));
}
}
}
System.out.println(mstWeight);
}
}
์ฝ๋๋ฅผ ํตํด ์ ์ ์๋ ๊ฒ์ฒ๋ผ KRUSKAL์ ๋นํด ์๋นํ ๋ณต์กํ๋ค. ๊ฐ์ ์ ๊ฐ์๊ฐ ์์ผ๋ฉด KRUSKAL ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๋๋ก ํ์.
3. ์๊ฐ๋ณต์ก๋ ๐ฅฝ
'๋ฐฉ๋ฒ 1 - ๋ฐ๋ณต๋ฌธ์ ํตํด ๋ค์ ์ ์ ์ ์ฐพ๋ ๋ฐฉ์'์์๋ O(V ^ 2)์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๋ค.
'๋ฐฉ๋ฒ 2 - PriorityQueue๋ฅผ ์ด์ฉํด ๋ค์ ์ ์ ์ ์ฐพ๋ ๋ฐฉ์'์์๋ O((E + V) log V)๋งํผ์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๋ค. (์๋ฐ์์๋ ์ฐ์ ์์ ํ๊ฐ ํผ๋ณด๋์น ํ์ด ์๋ ์ด์ง ํ ํํ์ด๊ธฐ ๋๋ฌธ์ด๋ค.) (๋ง์ฝ ํผ๋ณด๋์น ํ์ด๋ฉด O(E + VlogV)๋ฅผ ๊ฐ์ง๊ฒ ๋๋ค.)
(์๊ฐ๋ณต์ก๋ ๊ด๋ จํด์๋ ํด๋น ๊ธ์ ์ฐธ๊ณ ํ๊ธฐ ๋ฐ๋๋ค.)
์์์ ๊ณ์ํด์ ์ธ๊ธํ ๊ฒ์ฒ๋ผ ๊ฐ์ ์ ๊ฐ์์ ๋ฐ๋ผ์ KRUSKAL ์๊ณ ๋ฆฌ์ฆ๊ณผ PRIM ์๊ณ ๋ฆฌ์ฆ์ ์ ์ ํ๊ฒ ์ ํํด์ผ ํ๋ค.
'๐ ์๊ณ ๋ฆฌ์ฆ > ์ต์์ ์ฅํธ๋ฆฌ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
KRUSKAL ์๊ณ ๋ฆฌ์ฆ (0) | 2023.03.01 |
---|