博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
并查集——新手学习记录
阅读量:6271 次
发布时间:2019-06-22

本文共 2478 字,大约阅读时间需要 8 分钟。

好吧,什么垃圾并查集,并查集什么的都是铁憨憨<+__+>

现在开始复习回忆:(新手,有错误望指正)

什么叫做并查集,并查集就是一个集合问题,其实最主要的就是知道并查集是一个求解集合数目的问题,具体的操作方法有点飘。

或者这样理解:——并查集通过一个一维数组来实现,其本质是维护一个森林。(好吧,我也不是很理解),我的理解就是通过一维数组来实现,子节点与父节点之间联系,然后查找集合个数。。。。。。。

好吧,不清楚,如果看了前面你很懵逼,那就全都忘了吧,,,

接下来才是正餐:https://blog.51cto.com/ahalei/2348145

直接上代码:

题目是杭电的畅通工程:http://acm.hdu.edu.cn/showproblem.php?pid=1232

#include
int fa[1001]={
0};void zore(int n)//未知量用n表示,初始化{ for(int i=1;i<=n;i++) fa[i]=i;}int find_father(int x)//返回老大,或者说是根节点{ if(fa[x]== x) return x; else{ fa[x]=find_father(fa[x]);//优化路径 return fa[x]; }}void unions(int n,int m){ if(find_father(n)!=find_father(m)) fa[find_father(m)]=find_father(n);}int main(){ int n,m; while(scanf("%d %d",&n,&m)&&n) { int sum=0; zore(n); while(m--) { int a,b; scanf("%d %d",&a,&b); unions(a,b); } for(int i=1;i<=n;i++) { if(fa[i]==i) sum++; } printf("%d\n",sum-1); } return 0;}

现在我们把代码拆开来说:

int main(){    int n,m;//题目中的n代表城市个数,m代表道路数    while(scanf("%d %d",&n,&m)&&n)    {        int sum=0;//用来预装需要修的路数        zore(n);//调用初始化函数,来使我们的一维数组初始化        while(m--)//输入m条路        {            int a,b;//a,b分别代表道路的起始城市的标号            scanf("%d %d",&a,&b);            unions(a,b);//合并有相邻道路的城市,为最后计算道路数做准备:比如最后如果只有两个集合,只需要修一条路;三个集合两条路的思想。        }        for(int i=1;i<=n;i++)        {            if(fa[i]==i)//寻找到底有几个独立集合                 sum++;        }        printf("%d\n",sum-1);    }    return 0;} 

 接下来:

int fa[1001]={0};void zore(int n)//初始化作用,这点很重要,因为这个操作为我们接下来的操作提供了数据{    for(int i=1;i<=n;i++)        fa[i]=i;}

 再接下来:

int find_father(int x)//这个very very重要{  //作用是查找根结点,父节点...>如果你看过第一篇文章,你就把他理解成最大的BOOS就好了    if(fa[x]== x)如果查找点自己就是自己的最大BOOS,则返回        return x;    else{        fa[x]=find_father(fa[x]);//优化路径,其实 是一个递归调用        return fa[x];//优化过后改变了树的结构,  子节点很多直接变成了根结点           }}

  再接下来再:

void unions(int n,int m){    if(find_father(n)!=find_father(m))//合并操作..>其实就是当两个人的老大不一个人的时候,然而却需要建立联系,好吧,这个时候两个人就要开始干架了,最直接的方法是        fa[find_father(m)]=find_father(n);//直接让两个人的老大来谈话,让一个老大认另一个人的老大为老大,此时他们就属于同一个集合,此时就消除了集合间的隔离,或者说                                          //合并了两个集合 }

 

void unions(int x,int y){    int b1=find_father(n);//或者变成这样,x市到y市之间有一条路,查询x与y市的老大是谁    int b2=find_father(m);    if(b1!=b2)//判断x与y市在不在一个集合        fa[b1]=b2;//如果不在,合并}

 

转载于:https://www.cnblogs.com/gti2baby/p/10759760.html

你可能感兴趣的文章
SqlServer--bat批处理执行sql语句1-osql
查看>>
Linux系列教程(十八)——Linux文件系统管理之文件系统常用命令
查看>>
laravel安装初体验
查看>>
用yum查询想安装的软件
查看>>
TIJ -- 吐司BlockingQueue
查看>>
数据库分页查询
查看>>
[编程] C语言枚举类型(Enum)
查看>>
[Javascript] Compose multiple functions for new behavior in JavaScript
查看>>
ASP.NET MVC性能优化(实际项目中)
查看>>
ES6里关于类的拓展(一)
查看>>
零元学Expression Blend 4 - Chapter 46 三分钟快速充电-设定Margin的小撇步
查看>>
Format Conditions按条件显示表格记录
查看>>
RichTextBox指定全部文字显示不同颜色及部分文字高亮颜色显示
查看>>
mysql优化----explain的列分析
查看>>
Python正则表达式
查看>>
Java中CAS详解
查看>>
Spring Boot Unregistering JMX-exposed beans on shutdown
查看>>
命令行man的帮助手册
查看>>
Ubuntu 16.04下为Android编译OpenCV 3.2.0 Manager
查看>>
poi 导入导出的api说明(大全)
查看>>