最小生成樹MST
阿新 • • 發佈:2020-11-14
最小生成樹(Minimum Spanning Trees)
//kruskal-->MST #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct Edge { int src, dest, weight; }Edge; typedef struct Graph { int V, E; //V: 總節點數 E: 總邊數 Edge* edge; }Graph; Graph* createGraph(int V, int E) { Graph* graph = new Graph; graph->V = V; graph->E = E; graph->edge = new Edge[E]; return graph; } //union-find 並查集 typedef struct subset { int parent; int rank; //子樹深度,合併時用 }subset; int find(subset subsets[], int i) { if (subsets[i].parent != i) subsets[i].parent = find(subsets, subsets[i].parent); return subsets[i].parent; } //合併 集合 void Union(subset subsets[], int x, int y) { int xroot = find(subsets, x); int yroot = find(subsets, y); if (subsets[xroot].rank < subsets[yroot].rank) subsets[xroot].parent = yroot; else if (subsets[xroot].rank > subsets[yroot].rank) subsets[yroot].parent = xroot; else { subsets[yroot].parent = xroot; subsets[xroot].rank++; } } int mycomp(const void* a, const void* b) { // return ((Edge*)a)->weight > ((Edge*)b)->weight; return (*(Edge*)a).weight > (*(Edge*)b).weight; } /* *邊排序-> 遍歷-> 符合條件加入 */ void KruskalMST(Graph* graph) { int V = graph->V; Edge* result = (Edge*)malloc(V * sizeof(Edge)); int e = 0; int i = 0; qsort(graph->edge, graph->E, sizeof(graph->edge[0]), mycomp); subset* subsets = (subset*)malloc(V * sizeof(subset)); for (int v = 0; v < V; v++) { //初始化V個並查集 subsets[v].parent = v; subsets[v].rank = 0; } /*-------核心程式碼--------*/ while (e < V - 1 && i < graph->E) { //V個點,V-1條邊 Edge minEdge = graph->edge[i++]; int x = find(subsets, minEdge.src); int y = find(subsets, minEdge.dest); if (x != y) { result[e++] = minEdge; Union(subsets, x, y); } } /*--------------------*/ printf("edges in MST:\n"); int minCost = 0; for (i = 0; i < e; i++) { printf("%d ------ %d == %d\n", result[i].src, result[i].dest, result[i].weight); minCost += result[i].weight; } printf("minCost: %d\n", minCost); return; } int main() { //煮個栗子 int V = 4; int E = 5; Graph* graph = createGraph(V, E); graph->edge[0].src = 0; graph->edge[0].dest = 1; graph->edge[0].weight = 10; graph->edge[1].src = 0; graph->edge[1].dest = 2; graph->edge[1].weight = 6; graph->edge[2].src = 0; graph->edge[2].dest = 3; graph->edge[2].weight = 5; graph->edge[3].src = 1; graph->edge[3].dest = 3; graph->edge[3].weight = 15; graph->edge[4].src = 2; graph->edge[4].dest = 3; graph->edge[4].weight = 4; KruskalMST(graph); return 0; }