专题四 · 1001

来源:互联网 发布:redis数据持久化 编辑:程序博客网 时间:2024/05/17 08:36

代码及解释

#include <algorithm>#include <iostream>//// kruskal + 并查集 + 边表//struct node {  int from;  int to;  int w;};node edge[102 * 100];int parent[102];bool cmp(node a, node b) {  if (a.w <= b.w)    return true;  return false;}//查找已经建完道路的顶点int find(int a) {  if (a != parent[a])    return find(parent[a]);  else    return a;}int kruskal(int n, int m) {  std::sort(edge, edge + m, cmp); //将边的权值从小到大排序  int i, x, y, ans = 0;  for (i = 0; i < m; i++) {    x = edge[i].from;    y = edge[i].to;    x = find(x);    y = find(y);    if (x != y) {      ans += edge[i].w;      parent[y] = x;    }  }  return ans;}int main() {  int n, q, k, i, j, m;  while (std::cin >> n) {    m = 0;    for (i = 1; i <= n; i++) {      for (j = 1; j <= n; j++) {        std::cin >> k;        if (i >= j)          continue; //标记过的不用重复记录        edge[m].from = i;        edge[m].to = j;        edge[m].w = k;        m++;      }    }    for (k = 1; k <= n; k++)      parent[k] = k;    std::cin >> q;    //将建完的道路的起点和终点都置为相同的起点    for (k = 1; k <= q; k++) {      std::cin >> i >> j;      i = find(i);      j = find(j);      parent[j] = i;    }    // n个点,m条边    std::cout << kruskal(n, m) << std::endl;  }  return 0;}
0 0