最小生成树之克鲁斯卡尔算法

#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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值