์ ์ฅ ํธ๋ฆฌ๋ ๊ทธ๋ํ๋ด์
๋ชจ๋ ์ ์
์ ํฌํจํ๋ ํธ๋ฆฌ
- n๊ฐ์ ์ ์ ์ ๊ฐ์ง๋ ๊ทธ๋ํ์ ์ ์ฅํธ๋ฆฌ๋ n-1๊ฐ์ ๊ฐ์ ์ ๊ฐ์ง๋ค
- ํ๋์ ๊ทธ๋ํ์๋ ๋ง์ ์ ์ฅ ํธ๋ฆฌ๊ฐ ์กด์ฌํ ์ ์๋ค
- ๋ชจ๋ ์ ์ ๋ค์ด ์ฐ๊ฒฐ๋์ด ์์ด์ผ ํ๊ณ ์ฌ์ดํด์ด ํ์ฑ๋์๋ ์๋๋ค
DFS, BFS๋ฅผ ์ด์ฉํ์ฌ ์ ์ฅํธ๋ฆฌ๋ฅผ ์ฐพ์ ์ ์๋ค.
๋คํธ์ํฌ์ ์๋ ๋ชจ๋ ์ ์ ๋ค์ ๊ฐ์ฅ ์ ์ ์์ ๊ฐ์ ๊ณผ ๋น์ฉ์ผ๋ก ์ฐ๊ฒฐํ๋ ์๊ณ ๋ฆฌ์ฆ
- ๊ฐ์ ์ ๊ฐ์ค์น์ ํฉ์ด ์ต์์ฌ์ผ ํ๋ค
- n๊ฐ์ ์ ์ ์ ๊ฐ์ง๋ ๊ทธ๋ํ์ ๋ํด ๋ฐ๋์ n-1๊ฐ์ ๊ฐ์ ๋ง์ ์ฌ์ฉํด์ผ ํ๋ค
- ์ฌ์ดํด์ด ํฌํจ๋์ด์๋ ์๋๋ค.
ํ์์ ์ธ ๋ฐฉ๋ฒ(greedy method) ์ฌ์ฉ
- ๊ฐ ๋จ๊ณ์์ ์ต์ ์ ๋ต์ ์ ํํ๋ ๊ณผ์ ์ ๋ฐ๋ณต
- ํญ์ ์ต์ ์ ํด๋ฅผ ๊ฐ๋๋ค
์์๊ฐ ์ด๋ค ์งํฉ์ ์ํ๋์ง ์์๋ด๊ธฐ ์ํ ์๊ณ ๋ฆฌ์ฆ
- Kruskal's MST ์๊ณ ๋ฆฌ์ฆ์์ ์ฌ์ดํด ๊ฒ์ฌ์ ์ฌ์ฉ
int parent[MAX_VERTICES]; // ๋ถ๋ชจ ๋
ธ๋
void set_init(int n)
{
for(int i=0; i<n; i++>)
parent[i] = -1;
}
int set_find(int curr)
{
if(parent[curr] == -1)
return curr;
while(parent[curr] != -1)
curr=parrent[curr];
return curr;
}
void set_union(int a, int b)
{
int root1 = set_find(a); // ๋
ธ๋ a์ root๋ฅผ ์ฐพ๋๋ค.
int root2 = set_find(b); // ๋
ธ๋ b์ root๋ฅผ ์ฐพ๋๋ค.
if(root1 != root2) // ํฉํ๋ค.
parent[root1] = root2;
}
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define MAX_VERTICES 100
#define INF 1000
int parent[MAX_VERTICES]; // ๋ถ๋ชจ ๋
ธ๋
// ์ด๊ธฐํ
void set_init(int n)
{
for (int i = 0; i<n; i++)
parent[i] = -1;
}
// curr๊ฐ ์ํ๋ ์งํฉ์ ๋ฐํํ๋ค.
int set_find(int curr)
{
if (parent[curr] == -1)
return curr; // ๋ฃจํธ
while (parent[curr] != -1) curr = parent[curr];
return curr;
}
// ๋๊ฐ์ ์์๊ฐ ์ํ ์งํฉ์ ํฉ์น๋ค.
void set_union(int a, int b)
{
int root1 = set_find(a); // ๋
ธ๋ a์ ๋ฃจํธ๋ฅผ ์ฐพ๋๋ค.
int root2 = set_find(b); // ๋
ธ๋ b์ ๋ฃจํธ๋ฅผ ์ฐพ๋๋ค.
if (root1 != root2) // ํฉํ๋ค.
parent[root1] = root2;
}
struct Edge { // ๊ฐ์ ์ ๋ํ๋ด๋ ๊ตฌ์กฐ์ฒด
int start, end, weight;
};
typedef struct GraphType {
int n; // ๊ฐ์ ์ ๊ฐ์
struct Edge edges[2 * MAX_VERTICES];
} GraphType;
// ๊ทธ๋ํ ์ด๊ธฐํ
void graph_init(GraphType* g)
{
g->n = 0;
for (int i = 0; i < 2 * MAX_VERTICES; i++) {
g->edges[i].start = 0;
g->edges[i].end = 0;
g->edges[i].weight = INF;
}
}
// ๊ฐ์ ์ฝ์
์ฐ์ฐ
void insert_edge(GraphType* g, int start, int end, int w)
{
g->edges[g->n].start = start;
g->edges[g->n].end = end;
g->edges[g->n].weight = w;
g->n++;
}
// qsort()์ ์ฌ์ฉ๋๋ ํจ์
int compare(const void* a, const void* b)
{
struct Edge* x = (struct Edge*)a;
struct Edge* y = (struct Edge*)b;
return (x->weight - y->weight);
}
// kruskal์ ์ต์ ๋น์ฉ ์ ์ฅ ํธ๋ฆฌ ํ๋ก๊ทธ๋จ
void kruskal(GraphType *g)
{
int edge_accepted = 0; // ํ์ฌ๊น์ง ์ ํ๋ ๊ฐ์ ์ ์
int uset, vset; // ์ ์ u์ ์ ์ v์ ์งํฉ ๋ฒํธ
struct Edge e;
set_init(g->n); // ์งํฉ ์ด๊ธฐํ
qsort(g->edges, g->n, sizeof(struct Edge), compare);
printf("ํฌ๋ฃจ์ค์นผ ์ต์ ์ ์ฅ ํธ๋ฆฌ ์๊ณ ๋ฆฌ์ฆ \n");
int i = 0;
while (edge_accepted < (g->n - 1)) // ๊ฐ์ ์ ์ < (n-1)
{
e = g->edges[i];
uset = set_find(e.start); // ์ ์ u์ ์งํฉ ๋ฒํธ
vset = set_find(e.end); // ์ ์ v์ ์งํฉ ๋ฒํธ
if (uset != vset) { // ์๋ก ์ํ ์งํฉ์ด ๋ค๋ฅด๋ฉด
printf("๊ฐ์ (%d,%d) %d ์ ํ\n", e.start, e.end, e.weight);
edge_accepted++;
set_union(uset, vset); // ๋๊ฐ์ ์งํฉ์ ํฉ์น๋ค.
}
i++;
}
}
int main(void)
{
GraphType *g;
g = (GraphType *)malloc(sizeof(GraphType));
graph_init(g);
insert_edge(g, 0, 1, 29);
insert_edge(g, 1, 2, 16);
insert_edge(g, 2, 3, 12);
insert_edge(g, 3, 4, 22);
insert_edge(g, 4, 5, 27);
insert_edge(g, 5, 0, 10);
insert_edge(g, 6, 1, 15);
insert_edge(g, 6, 3, 18);
insert_edge(g, 6, 4, 25);
kruskal(g);
free(g);
return 0;
}
์์ ์ ์ ์์๋ถํฐ ์ถ๋ฐํ์ฌ ์ ์ฅ ํธ๋ฆฌ ์งํฉ์ ๋จ๊ณ์ ์ผ๋ก ํ์ฅํด๋๊ฐ๋ ๋ฐฉ๋ฒ
- ์ ์ฅ ํธ๋ฆฌ ์งํฉ์์ ์ธ์ ํ ์ ์ ์ค์์ ์ต์ ๊ฐ์ ์ผ๋ก ์ฐ๊ฒฐ๋ ์ ์ ์ ์ ํํ์ฌ ์ ์ฅ ํธ๋ฆฌ ์งํฉ์ ์ถ๊ฐ
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define MAX_VERTICES 100
#define INF 1000L
typedef struct GraphType {
int n; // ์ ์ ์ ๊ฐ์
int weight[MAX_VERTICES][MAX_VERTICES];
} GraphType;
int selected[MAX_VERTICES];
int distance[MAX_VERTICES];
// ์ต์ dist[v] ๊ฐ์ ๊ฐ๋ ์ ์ ์ ๋ฐํ
int get_min_vertex(int n)
{
int v, i;
for (i = 0; i <n; i++)
if (!selected[i]) {
v = i;
break;
}
for (i = 0; i < n; i++)
if (!selected[i] && (distance[i] < distance[v])) v = i;
return (v);
}
void prim(GraphType* g, int s)
{
int i, u, v;
for (u = 0; u<g->n; u++)
distance[u] = INF;
distance[s] = 0;
for (i = 0; i<g->n; i++) {
u = get_min_vertex(g->n);
selected[u] = TRUE;
if (distance[u] == INF) return;
printf("์ ์ %d ์ถ๊ฐ\n", u);
for (v = 0; v<g->n; v++)
if (g->weight[u][v] != INF)
if (!selected[v] && g->weight[u][v]< distance[v])
distance[v] = g->weight[u][v];
}
}
int main(void)
{
GraphType g = { 7,
{{ 0, 29, INF, INF, INF, 10, INF },
{ 29, 0, 16, INF, INF, INF, 15 },
{ INF, 16, 0, 12, INF, INF, INF },
{ INF, INF, 12, 0, 22, INF, 18 },
{ INF, INF, INF, 22, 0, 27, 25 },
{ 10, INF, INF, INF, 27, 0, INF },
{ INF, 15, INF, 18, 25, INF, 0 } }
};
prim(&g, 0);
return 0;
}