c // Prim算法实现 void prim(int n, int graph[][MAX], int parent[], int dist[], bool mstSet[]) { // 初始化dist数组和mstSet数组 for (int i = 0; i < n; i++) { dist[i] = INT_MAX, mstSet[i] = false; }
// 从任意节点开始 dist[0] = 0; parent[0] = -1;
for (int count = 0; count < n - 1; count++) { // 找到未加入树中且与已加入树中节点距离最短的节点 int u = findMin(dist, mstSet);
// 将当前节点加入到树中 mstSet[u] = true;
// 更新与当前节点相邻且距离最小的未加入树中节点的距离 for (int v = 0; v < n; v++) if (graph[u][v] && !mstSet[v] && graph[u][v] < dist[v]) parent[v] = u, dist[v] = graph[u][v]; } }
Kruskal算法实现代码如下:
c // Kruskal算法实现 void kruskal(int n, int graph[][MAX], int parent[], int rank[]) { // 初始化并查集 for (int i = 0; i < n; i++) parent[i] = i;
// 按权值排序边 sort(graph, graph + n * n);
int edgeCount = 0, treeCount = n; int mstWeight = 0;
// 遍历排序后的边,选取权值最小且不构成回路的边 for (int i = 0; i < n * n; i++) { int u = find(parent, graph[i][0]), v = find(parent, graph[i][1]); if (u != v) { // 将边加入最小生成树 mstWeight += graph[i][2]; merge(parent, rank, u, v); edgeCount++; } // 检查是否构成最小生成树 if (edgeCount == n - 1) break; } // 输出最小生成树权值 printf("Minimum Spanning Tree Weight: %d\n", mstWeight); }
// 查找并查集中的代表节点 int find(int parent[], int i) { if (parent[i] == i) return i; return parent[i] = find(parent, parent[i]); }
// 合并两个集合 void merge(int parent[], int rank[], int x, int y) { if (rank[x] < rank[y]) parent[x] = y; else if (rank[x] > rank[y]) parent[y] = x; else { parent[y] = x; rank[x]++; } }