zoukankan      html  css  js  c++  java
  • 数据结构4 并查集

    • 查找的时候才更新的时候
    • 合并的时候不更新
     1 #include  <iostream>
     2 using namespace std;
     3 #define N 100
     4 int father[N];
     5 int n, m;
     6 
     7 void init(){
     8     for(int i=1; i<=n; i++)
     9         father[i] = i;
    10 }
    11 
    12 //查找
    13 int Find(int x){
    14     if(x != father[x])
    15         father[x] = Find(father[x]);
    16     return father[x]; // 一直要找到 x = father[x] 返回
    17 }
    18 
    19 
    20 // 合并
    21 void Union(int x, int y){
    22     int a, b;
    23     a = Find(x);
    24     b = Find(y);
    25     if(a != b)
    26         father[b] = a;  // 这边是随便给的,没有影响
    27 }
    28 
    29 int main(){
    30     int x, u, v, sum=0;
    31     cout << "input n and m:" << endl;
    32     cin >> n >> m;
    33     init();
    34     cout << "input u and v" << endl;
    35     for(int i=1; i<=m; i++){
    36         cin >> u >> v;
    37         Union(u, v);
    38     }
    39     
    40     for(int i=1; i<=n; i++){
    41         Find(i);  // 每次查找的时候更新数组
    42         cout << father[i] << " ";
    43         if(father[i]==i)
    44             sum++;
    45     }
    46     cout << endl;
    47     cout << "sum=" << sum << endl;
    48     return 0;
    49 }

    测试数据:

     10 9

     1 2

     3 4

     5 2

     4 6

     2 6

     8 7

     9 7

     1 6

     2 4

    每个节点都执行一次find,来完成路径压缩。

    使用并查集改进Kruskal

    先对边排序,然后使用并查集选边

     1 #include <iostream>
     2 #include <algorithm>
     3 using namespace std;
     4 
     5 const int N=100;
     6 int father[N];
     7 int n, m;  // 节点数,边数
     8 
     9 struct Edge{  // kruskal对边进行排序
    10     int u, v, w;
    11 }e[N*N];
    12 // 有向图 n(n-1)/2  无向图 n(n-1)
    13 
    14 bool cmp(Edge x, Edge y){
    15     return x.w < y.w;
    16 }
    17 
    18 void Init(int n){  // 节点从1到n
    19     for(int i=1; i<=n; i++)
    20         father[i] = i;
    21 }
    22 
    23 int Find(int x){
    24     if(x != father[x])
    25         father[x] = Find(father[x]);  // 调用它父亲的集合号
    26     return father[x];
    27 }
    28 bool Union(int x, int y){
    29     int a = Find(x);
    30     int b = Find(y);
    31     if(a==b) return 0;
    32     
    33     if(a > b){  // 小的赋值给大的集合号
    34         father[a] = b;
    35     }else{
    36         father[b] = a;
    37     }
    38     return true;
    39 }
    40 
    41 int Kruskal(int n){
    42     int ans = 0;
    43     for(int i=0; i<m; i++){
    44         if(Union(e[i].u, e[i].v)){
    45             ans += e[i].w;
    46             n--;
    47             if(n == 1)  // 我们要选n-1条边
    48                 return ans;
    49         }
    50     }
    51     return 0;
    52 }
    53 int main(){
    54     cout << "输入结点数n和边数m:" << endl;
    55     cin >> n >> m;
    56     Init(n);
    57     cout << "输入结点u,v和边权w:" << endl;
    58     for(int i=0; i<m; i++)
    59         cin >> e[i].u >> e[i].v >> e[i].w;
    60     sort(e, e+m, cmp);
    61     int ans = Kruskal(n);
    62     cout << "最小的化费是:" << ans << endl;
    63     int sum = 0;
    64     for(int i=1; i<=n; i++){
    65         cout << father[i] << " ";
    66         if(father[i] == i)
    67             sum++;
    68     }
    69     cout << endl;
    70     cout << "sum = " << sum << endl;
    71     return 0;
    72 }

     7 12

     1 2 23

     1 6 28

     1 7 36

     2 3 20

     2 7 1

     3 4 15

     3 7 4

     4 5 3

     4 7 9

     5 6 16

     5 7 16

     6 7 25

  • 相关阅读:
    Linux 下的类似Windows下Everything的搜索工具
    windows和linux环境下制作U盘启动盘
    程序调试手段之gdb, vxworks shell
    LeetCode 1021. Remove Outermost Parentheses (删除最外层的括号)
    LeetCode 1047. Remove All Adjacent Duplicates In String (删除字符串中的所有相邻重复项)
    LeetCode 844. Backspace String Compare (比较含退格的字符串)
    LeetCode 860. Lemonade Change (柠檬水找零)
    LeetCode 1221. Split a String in Balanced Strings (分割平衡字符串)
    LeetCode 1046. Last Stone Weight (最后一块石头的重量 )
    LeetCode 746. Min Cost Climbing Stairs (使用最小花费爬楼梯)
  • 原文地址:https://www.cnblogs.com/JCcodeblgos/p/11524696.html
Copyright © 2011-2022 走看看