kruskal ์๊ณ ๋ฆฌ์ฆ ๊ตฌํ(c์ธ์ด)
#include <stdio.h>
#include <stdlib.h>
typedef struct Edge
{
char v1, v2;
int weight;
struct Edge* next;
}Edge;
typedef struct IncidentEdge
{
char aName;
Edge* e;
struct IncidentEdge* next;
}IncidentEdge;
typedef struct Vertex
{
char vName;
IncidentEdge* iHead;
struct Vertex* next;
}Vertex;
typedef struct
{
Vertex* vHead;
Edge* eHead;
int eCount, vCount;
}Graph;
void init(Graph* G)
{
G->vHead = NULL;
G->eHead = NULL;
G->vCount = G->eCount = 0;
}
void makeVertex(Graph* G, char vName)
{
Vertex* v = (Vertex*)malloc(sizeof(Vertex));
v->vName = vName;
v->iHead = NULL;
v->next = NULL;
G->vCount++;
Vertex* q = G->vHead;
if (q == NULL)
G->vHead = v;
else
{
while (q->next != NULL)
q = q->next;
q->next = v;
}
}
void makeIncidentEdge(Vertex* v, char aName, Edge* e)
{
IncidentEdge* p = (IncidentEdge*)malloc(sizeof(IncidentEdge));
p->aName = aName;
p->e = e;
p->next = NULL;
IncidentEdge* q = v->iHead;
if (q == NULL)
v->iHead = p;
else
{
while (q->next != NULL)
q = q->next;
q->next = p;
}
}
Vertex* findVertex(Graph* G, char vName)
{
Vertex* v = G->vHead;
while (v->vName != vName)
v = v->next;
return v;
}
void insertEdge(Graph* G, char v1, char v2, int w)
{
Edge* e = (Edge*)malloc(sizeof(Edge));
e->weight = w;
e->v1 = v1;
e->v2 = v2;
e->next = NULL;
G->eCount++;
Edge* q = G->eHead;
if (q == NULL)
G->eHead = e;
else
{
while (q->next != NULL)
q = q->next;
q->next = e;
}
Vertex* v = findVertex(G, v1);
makeIncidentEdge(v, v2, e);
v = findVertex(G, v2);
makeIncidentEdge(v, v1, e);
}
void print(Graph* G)
{
Vertex* p = G->vHead;
IncidentEdge* q;
for (; p != NULL; p = p->next)
{
printf("[%c] : ", p->vName);
for (q = p->iHead; q != NULL; q = q->next)
printf("[%c, %d] ", q->aName, q->e->weight);
printf("\n");
}
printf("\n");
}
void incSort(Graph* G, Edge* e[])
{
int i, least;
Edge* p = G->eHead;
for(i = 0; i < G->eCount; i++)
{
e[i] = p;
p = p->next;
}
for (i = 0; i < G->eCount - 1; i++)
{
least = i;
for (int j = i + 1; j < G->eCount; j++)
if (e[j]->weight < e[least]->weight)
least = j;
p = e[least];
e[least] = e[i];
e[i] = p;
}
for(i = 0; i < G->eCount; i++)
printf("[%c%c(%d)] ", e[i]->v1, e[i]->v2, e[i]->weight);
printf("\n\n");
}
int vFind(int v[], int vNum)
{
if(v[vNum] == -1)
return vNum;
while(v[vNum] != -1)
vNum = v[vNum];
return vNum;
}
void vUnion(int v[], int vNum1, int vNum2)
{
int r1 = vFind(v, vNum1);
int r2 = vFind(v, vNum2);
if(r1 != r2)
v[r2] = r1;
}
void kruskal(Graph* G, Edge* e[], int v[])
{
int eCnt = 0, i = 0;
int vNum1, vNum2;
Edge* p;
while(eCnt < G->vCount - 1)
{
p = e[i];
vNum1 = vFind(v, p->v1 - 97);
vNum2 = vFind(v, p->v2 - 97);
if(vNum1 != vNum2)
{
printf("%d. [%c%c (%d)]\n", eCnt+1, p->v1, p->v2, p->weight);
eCnt++;
vUnion(v, vNum1, vNum2);
}
i++;
}
}
int main()
{
Graph G;
init(&G);
makeVertex(&G, 'a'); makeVertex(&G, 'b'); makeVertex(&G, 'c');
makeVertex(&G, 'd'); makeVertex(&G, 'e'); makeVertex(&G, 'f');
insertEdge(&G, 'a', 'b', 8); insertEdge(&G, 'a', 'd', 2);
insertEdge(&G, 'a', 'e', 4); insertEdge(&G, 'b', 'c', 1);
insertEdge(&G, 'b', 'd', 4); insertEdge(&G, 'b', 'f', 2);
insertEdge(&G, 'c', 'f', 1); insertEdge(&G, 'd', 'e', 3);
insertEdge(&G, 'd', 'f', 7); insertEdge(&G, 'e', 'f', 9);
print(&G);
Edge* e[20];
incSort(&G, e);
int v[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
kruskal(&G, e, v);
return 0;
}
์๊ฐ๋ณต์ก๋
์ ๋ ฌํ๋๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ O(mlogm)
while ๋ฃจํ๋ ์ต๋ m๋ฒ ์ํ
->O(mlogm)
prim ์๊ณ ๋ฆฌ์ฆ ๊ตฌํ(C์ธ์ด)
#include <stdio.h>
#include <stdlib.h>
//๋ฐฉ๋ฌธ ์ ์ ์ vertex ๊ตฌ์กฐ์ฒด์ ์ง์ด๋ฃ์ ๊ฒ
#define FALSE 0
#define TRUE 1
typedef struct Edge
{
char v1, v2;
int weight;
struct Edge* next;
}Edge;
typedef struct IncidentEdge
{
char aName;
Edge* e;
struct IncidentEdge* next;
}IncidentEdge;
typedef struct Vertex
{
char vName;
int isVisit;
IncidentEdge* iHead;
struct Vertex* next;
}Vertex;
typedef struct
{
Vertex* vHead;
Edge* eHead;
int eCount, vCount;
}Graph;
void init(Graph* G)
{
G->vHead = NULL;
G->eHead = NULL;
G->vCount = G->eCount = 0;
}
void makeVertex(Graph* G, char vName)
{
Vertex* v = (Vertex*)malloc(sizeof(Vertex));
v->vName = vName;
v->isVisit=FALSE;
v->iHead = NULL;
v->next = NULL;
G->vCount++;
Vertex* q = G->vHead;
if (q == NULL)
G->vHead = v;
else
{
while (q->next != NULL)
q = q->next;
q->next = v;
}
}
void makeIncidentEdge(Vertex* v, char aName, Edge* e)
{
IncidentEdge* p = (IncidentEdge*)malloc(sizeof(IncidentEdge));
p->aName = aName;
p->e = e;
p->next = NULL;
IncidentEdge* q = v->iHead;
if (q == NULL)
v->iHead = p;
else
{
while (q->next != NULL)
q = q->next;
q->next = p;
}
}
Vertex* findVertex(Graph* G, char vName)
{
Vertex* v = G->vHead;
while (v->vName != vName)
v = v->next;
return v;
}
void insertEdge(Graph* G, char v1, char v2, int w)
{
Edge* e = (Edge*)malloc(sizeof(Edge));
e->weight = w;
e->v1 = v1;
e->v2 = v2;
e->next = NULL;
G->eCount++;
Edge* q = G->eHead;
if (q == NULL)
G->eHead = e;
else
{
while (q->next != NULL)
q = q->next;
q->next = e;
}
Vertex* v = findVertex(G, v1);
makeIncidentEdge(v, v2, e);
v = findVertex(G, v2);
makeIncidentEdge(v, v1, e);
}
void print(Graph* G)
{
Vertex* p = G->vHead;
IncidentEdge* q;
for (; p != NULL; p = p->next)
{
printf("[%c] : ", p->vName);
for (q = p->iHead; q != NULL; q = q->next)
printf("[%c, %d] ", q->aName, q->e->weight);
printf("\n");
}
printf("\n");
}
char getMinVertex(Graph* G, int D[]){
Vertex* p=G->vHead;
char vName;
for(;p!=NULL;p=p->next){
if(p->isVisit==FALSE){
vName=p->vName;
break;
}
}
for(p=G->vHead;p!=NULL;p=p->next){
if(p->isVisit==FALSE&&(D[p->vName-97]<D[vName-97])){
vName=p->vName;
}
}
return vName;
}
void prim(Graph* G, char vName, int D[]){
Vertex* p=findVertex(G,vName);
//์ ์ c์ ์ฃผ์๊ฐ ์ฒ์์ ๋์
๋จ
IncidentEdge* q;
char c;
D[p->vName-97]=0;
for(int i=0;i<G->vCount;i++){
c=getMinVertex(G,D);
p=findVertex(G,c); //์ ์ ๋
ธ๋๋ฅผ ์ฐพ์
p->isVisit=TRUE; //๋ฐฉ๋ฌธํ ๋
ธ๋ check
printf("(%c) ",p->vName);
for(q=p->iHead; q!=NULL;q=q->next){
p=findVertex(G,q->aName);
if(p->isVisit==FALSE)
D[q->aName-97]=q->e->weight;
}
}
}
int main()
{
Graph G;
init(&G);
makeVertex(&G, 'a'); makeVertex(&G, 'b'); makeVertex(&G, 'c');
makeVertex(&G, 'd'); makeVertex(&G, 'e'); makeVertex(&G, 'f');
insertEdge(&G, 'a', 'b', 3); insertEdge(&G, 'a', 'd', 2);
insertEdge(&G, 'a', 'e', 4); insertEdge(&G, 'b', 'c', 1);
insertEdge(&G, 'b', 'd', 4); insertEdge(&G, 'b', 'f', 2);
insertEdge(&G, 'c', 'f', 1); insertEdge(&G, 'd', 'e', 5);
insertEdge(&G, 'd', 'f', 7); insertEdge(&G, 'e', 'f', 9);
print(&G);
int D[10]={100,100,100,100,100,100,100,100,100,100};
prim(&G, 'c', D);
return 0;
}
์๊ฐ๋ณต์ก๋
์ค์ฒฉ๋๋ ๋ฐ๋ณต๋ฌธ์ด ์กด์ฌ
while ๋ฃจํ๊ฐ (n-1)ํ ๋ฐ๋ณต
1๋ฒ ์คํ๋ ๋ O(n)์๊ฐ ์์
-->O(n^2)
*์ต์ ํ(Binary Heap)์ ์ฌ์ฉํ์ฌ vmin์ ์ฐพ์ผ๋ฉด O(mlogn)
m์ ๊ฐ์ ์์ด๋ฏ๋ก ๊ฐ์ ์๊ฐ n์ด๋ฉด O(nlogn)
'๐ป ์๊ณ ๋ฆฌ์ฆ > ์ด๋ก ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋์ ๊ณํ ์๊ณ ๋ฆฌ์ฆ(DP/Dynamic Programming) (0) | 2022.04.18 |
---|---|
๊ทธ๋ฆฌ๋(Greedy)/ํ์ ๊ธฐ๋ฒ (0) | 2022.04.15 |
๋ถํ ์ ๋ณต(Divide and Conquer) - ์ต๊ทผ์ ์ ์ ์ ์ฐพ๊ธฐ (0) | 2022.04.11 |
๋ถํ ์ ๋ณต(Divide and Conquer) (0) | 2022.04.10 |