杭电1102——最小生成树+并差集

kruskal 配并差集
模板题

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;

const int mx = 105;
//存储节点上级
int f[mx];

//存储两节点之间的距离
struct node {
  int a, b;
  double val;
};
//计算两个节点之间的距离
double length(double a[], double b[]) {
  return sqrt((a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]));
}
//排序op
bool cmp(node a, node b) {
  return a.val < b.val;
}
//初始化数组,设置每个节点的上级是自己
void init() {
  for (int i = 0; i < mx; i++) f[i] = i;
}
//寻找x节点的最上级
int fin(int x) {
  return f[x] = x == f[x] ? x : fin(f[x]);
}
//将x节点和y节点连接起来
void merge(int x, int y) {
  f[fin(x)] = fin(y);
}
//判断x节点和y节点是否已经连接
bool same(int x, int y) {
  return fin(x) == fin(y);
}

int main() {
  //freopen("in.txt", "r", stdin);
  int n;
  while (cin >> n) {
    //初始化
    init();
    int cnt = 0;
    node len[mx * mx];
    //输入每个节点与其他节点的距离
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) {
        len[cnt].a = i;
        len[cnt].b = j;
        cin >> len[cnt++].val;
      }
    }
    int Q; cin >> Q;
    //输入本来就连接的节点,直接连接,不用计算距离
    while (Q--) {
      int a, b; cin >> a >> b;
      if (!same(a, b)) merge(a, b);
    }
    //按照距离从小到大排序
    sort(len, len + cnt, cmp);
    double sum = 0;
    for (int i = 0; i < cnt; i++) {
      if (!same(len[i].a, len[i].b)) {
        //将符合条件的两个节点连接起来
        merge(len[i].a, len[i].b);
        sum += len[i].val;
      }
    }
    cout << sum << endl;
  }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值