zoukankan      html  css  js  c++  java
  • Kruskal算法:最小生成树

    //Kruskal算法按照边的权值从小到大查看一遍,如果不产生圈(重边等也算在内),就把当前这条表加入到生成树中。

    //如果判断是否产生圈。假设现在要把连接顶点u和顶点v的边e加入生成树中。如果加入之前的u和v不在同一个连通分量里,那么加入e也不会产生圈。

    //反之,如果u和v在同一个连通分量里,那一定会产生圈。可以用并查集高效判断是否属于同一个连通分量。

      1 #define _CRT_SECURE_NO_WARNINGS
      2 /*
      3 7 10
      4 0 1 5
      5 0 2 2
      6 1 2 4
      7 1 3 2
      8 2 3 6
      9 2 4 10
     10 3 5 1
     11 4 5 3
     12 4 6 5
     13 5 6 9
     14 */
     15 #include <iostream>
     16 #include <vector>
     17 #include <algorithm>
     18 using namespace std;
     19 
     20 const int maxn = 1010 + 10;
     21 const int INF = 9999999;
     22 int par[maxn];     //父亲,  当par[x] = x时,x是所在的树的根
     23 int Rank[maxn];    //树的高度
     24 struct edge
     25 {
     26     int u, v, cost;
     27 };
     28 
     29 bool comp(const edge& e1, const edge& e2) {
     30     return e1.cost < e2.cost;
     31 }
     32 
     33 edge es[maxn];
     34 int V, E;        //顶点数和边数
     35 //并查集实现-高效的判断是否属于同一个连通分量。
     36 void init_union_find(int n);
     37 int find(int x);
     38 void unite(int x, int y);
     39 bool same(int x, int y);
     40 void init();
     41 void input();
     42 int kruskal();   //最小生成树算法
     43 
     44 //初始化n个元素
     45 void init_union_find(int n)
     46 {
     47     for (int i = 0; i < n; i++) {
     48         par[i] = i;
     49         Rank[i] = 0;
     50     }
     51 }
     52 
     53 //查询树的根
     54 int find(int x) {
     55     if (par[x] == x) {
     56         return x;
     57     }
     58     else {
     59         return par[x] = find(par[x]);
     60     }
     61 }
     62 
     63 //合并x和y所属集合
     64 void unite(int x, int y) {
     65     x = find(x);
     66     y = find(y);
     67     if (x == y) return;
     68 
     69     if (Rank[x] < Rank[y]) {
     70         par[x] = y;
     71     }
     72     else {
     73         par[y] = x;
     74         if (Rank[x] == Rank[y]) Rank[x]++;    //如果x,y的树高相同,就让x的树高+1
     75     }
     76 }
     77 
     78 //判断x和y是否属于同一个集合
     79 bool same(int x, int y) {
     80     return find(x) == find(y);
     81 }
     82 
     83 void init() {
     84 
     85 }
     86 
     87 void input()
     88 {
     89     edge tmp;
     90     for (int i = 0; i < E; i++) {
     91         cin >> tmp.u >> tmp.v >> tmp.cost;
     92         es[i] = tmp;
     93     }
     94 }
     95 
     96 int kruskal()
     97 {
     98     sort(es, es + E, comp); //按照edge.cost的顺序从小到大排序
     99     init_union_find(V);     //将并查集初始化
    100     int res = 0;
    101     for (int i = 0; i < E; i++) {
    102         edge e = es[i];
    103         if (!same(e.u, e.v)) {
    104             unite(e.u, e.v);
    105             res += e.cost;
    106         }
    107     }
    108     return res;
    109 }
    110 
    111 int main()
    112 {
    113     cin >> V >> E;
    114     input();
    115     int res = kruskal();
    116     cout << res << endl;
    117     return 0;
    118 }
  • 相关阅读:
    在javaWeb 工程中 tomcat 的 web.xml 文件配置
    Spring 框架详解
    构建工具 Maven和Gradle对比
    idea 创建Javaweb 动态工程
    服务器后端 项目代码常用目录图
    ET模式下的EPOLLOUT
    linux recv 参数len设置为0
    fork 和 exec 对子进程继承父进程处理信号处理函数的影响
    lua元表以及元方法
    Linux网络编程“惊群”问题总结
  • 原文地址:https://www.cnblogs.com/douzujun/p/6418281.html
Copyright © 2011-2022 走看看