#include"iostream"
#include"algorithm"
using namespace std;
struct Edge {
int begin; //边起始点
int end; //边结束点
int weight; //边的权重
};
//用于把所有边按权重的大小排序
bool comp(const Edge& e1, const Edge& e2) {
return e1.weight < e2.weight;
}
/*
使用<span style="font-size:14px;">并查集</span>来判断两个点是否在同一个连通块中。在每个连通块中,用一个节点来代表该块中的其他节点,
那么如果两个节点的代表节点相同,则说明这两个节点在同
一个连通块中,所以如果把这两个节点的边加入最小生成树中,
则会形成环路
*/
int find(int e[], int n) {
while (e[n] > 0) {
n = e[n];
}
return n;
}
//e[]是按权值大小从小到大排好序了
void fun(Edge e[], int n) {
int edge[20]; //保存每个节点的代表节点
for (int i = 0; i < 20; i++)
edge[i] = 0;
for (int i = 0; i < n; i++) {
int begin = e[i].begin;
int end = e[i].end;
int n = find(edge, begin); //n为节点begin的代表节点
int m = find(edge, end); //m为节点end的代表节点
if (n != m) { //两个代表节点不相同,说明不会形成环路
edge[n] = m; //修改节点n的代表节点
cout << begin << " " << end << " " << e[i].weight << endl;
}
}
}
int main() {
Edge edges[15];
//测试图
edges[0].begin = 4, edges[0].end = 5, edges[0].weight = 26;
edges[1].begin = 3, edges[1].end = 6, edges[1].weight = 24;
edges[2].begin = 2, edges[2].end = 3, edges[2].weight = 22;
edges[3].begin = 3, edges[3].end = 8, edges[3].weight = 21;
edges[4].begin = 3, edges[4].end = 4, edges[4].weight = 20;
edges[5].begin = 6, edges[5].end = 7, edges[5].weight = 19;
edges[6].begin = 1, edges[6].end = 2, edges[6].weight = 18;
edges[7].begin = 5, edges[7].end = 6, edges[7].weight = 17;
edges[8].begin = 1, edges[8].end = 6, edges[8].weight = 16;
edges[9].begin = 3, edges[9].end = 7, edges[9].weight = 16;
edges[10].begin = 1, edges[10].end = 8, edges[10].weight = 12;
edges[11].begin = 0, edges[11].end = 5, edges[11].weight = 11;
edges[12].begin = 0, edges[12].end = 1, edges[12].weight = 10;
edges[13].begin = 2, edges[13].end = 8, edges[13].weight = 8;
edges[14].begin = 4, edges[14].end = 7, edges[14].weight = 7;
sort(edges, edges + 15, comp); //按边的权重大小进行排序
fun(edges,15);
return 0;
}
最小生成树之克鲁斯卡尔算法
最新推荐文章于 2021-10-27 19:10:10 发布