并查集(以hdu 1232 畅通工程为例)

HDU 1232 畅通工程 并查集入门经典 OJ题解 HDU1232 畅通工程一、背景简介二、题目描述Problem DescriptionInputOutputSample InputSample Output三、题解思路四、AC代码完整代码其他参考 一、背景简介 此题为并查集的经典例题,入门水准。如果想学习这个数据结构,一定要好好学习这个基础,模版可以背下来。题目来源为HDU 1232,具体链接为:http://acm.hdu.edu.cn/showproblem.php?pid=1232。 二、题目描述 Problem Description 某省调查城 阅读详情
在讲并查集之前我们先举一个例子。(这个例子是出自别人之手)
话说江湖上散落着各式各样的大侠,有上千个之多。他们没有什么正当职业,整天背着剑在外面走来走去,碰到和自己不是一路人的,就免不了要打一架。但大侠们有一个优点就是讲义气,绝对不打自己的朋友。而且他们信奉“朋友的朋友就是我的朋友”,只要是能通过朋友关系串联起来的,不管拐了多少个弯,都认为是自己人。这样一来,江湖上就形成了一个一个的群落,通过两两之间的朋友关系串联起来。而不在同一个群落的人,无论如何都无法通过朋友关系连起来,于是就可以放心往死了打。但是两个原本互不相识的人,如何判断是否属于一个朋友圈呢?
我们可以在每个朋友圈内推举出一个比较有名望的人,作为该圈子的代表人物,这样,每个圈子就可以这样命名“齐达内朋友之队”“罗纳尔多朋友之队”……两人只要互相对一下自己的队长是不是同一个人,就可以确定敌友关系了。
但是还有问题啊,大侠们只知道自己直接的朋友是谁,很多人压根就不认识队长,要判断自己的队长是谁,只能漫无目的的通过朋友的朋友关系问下去:“你是不是队长?你是不是队长?”这样一来,队长面子上挂不住了,而且效率太低,还有可能陷入无限循环中。于是队长下令,重新组队。队内所有人实行分等级制度,形成树状结构,我队长就是根节点,下面分别是二级队员、三级队员。每个人只要记住自己的上级是谁就行了。遇到判断敌友的时候,只要一层层向上问,直到最高层,就可以在短时间内确定队长是谁了。由于我们关心的只是两个人之间是否连通,至于他们是如何连通的,以及每个圈子内部的结构是怎样的,甚至队长是谁,并不重要。所以我们可以放任队长随意重新组队,只要不搞错敌友关系就好了。于是,门派产生了。

这里写图片描述
接下来我们看一下并查集的实现,定义一个 fat[2000]数组,记录了每个大侠的上级是谁。大侠们从1或者0开始给自己编号(这个地方根据题意来定)。fat[3]=2;就是代表3号大侠的上级就是2号大侠。如果一个人的上级就是他自己的话,则说明他就是掌门人,也就是查找到这就可以结束。也有孤家寡人自成一派的,比如欧阳锋,那么他的上级就是他自己。每个人都只认自己的上级。比如胡青牛同学只知道自己的上级是杨左使。张无忌是谁?不认识!要想知道自己的掌门是谁,只能一级级查上去。 find这个函数就是找掌门用的,意义再清楚不过了(路径压缩、按秩合并算法后面再说)。
先来写一些初始化这个函数

int fat[N];

void init(int n)
{
    for(int i=1; i<=n; i++) 
        fat[i]=i;//初始化每个人的上级都是自己
}

紧接着是find函数

int find(int x)   //查找x的掌门
{
    int r=x;       
    while(fat[r]!=r)    //如果r的上级不是r自己(也就是说找到的大侠不是掌门)
        r=fat[r]; //r就接着找他的上级,直到找到掌门为止
    return r; //返回掌门
}

接下来介绍一下union合并函数,它的最初的意思可以理解为两个点之间连一条线,这样他们原先所在的板块的所有点就都可以互通了。

void union(int a,int b)  //想让a与b做朋友
{
    int xx=find(a),yy=find(b); //然后去赵他们的上级去判断他们的上级是不是一个人
    if(xx!=yy)
        fat[xx]=yy;
}

介绍一下 路径压缩

int find(int x) //路径压缩 循环
{
int r=x;
while(r!=fat[r])
r=fat[r];
int t=x,j;
while(t!=r)//循环
{
j=fat[t];
fat[t]=r;
t=j;
}
return r;
}

int find(int x) //路径压缩 递归
{

if(fat[x]==x) return x;
return find(fat[x]);
}

过程如下:
这里写图片描述
按秩合并,按秩合并就是将短的连到长的上。该方法使用秩来表示树高度的上界,在合并时,总是将具有较小秩的树根指向具有较大秩的树根。简单的说,就是总是将比较矮的树作为子树,添加到较高的树中。

void Union(int a,int b) //按秩合并
{
    int xx=Find(a),yy=Find(b);
    if(xx==yy)
        return ;
    if(ran[xx]>ran[yy])
        fat[yy]=xx;
    else
    {
        if(ran[xx]==ran[yy])
            ran[yy]++;
        fat[xx]=yy;
    }
}

过程如下:
这里写图片描述

最后以hdu 1232 为例

Problem Description
某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路? 
 

Input
测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是城镇数目N ( < 1000 )和道路数目M;随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号。为简单起见,城镇从1到N编号。 
注意:两个城市之间可以有多条道路相通,也就是说
3 3
1 2
1 2
2 1
这种输入也是合法的
当N为0时,输入结束,该用例不被处理。 
 

Output
对每个测试用例,在1行里输出最少还需要建设的道路数目。 
 

Sample Input
4 2
1 3
4 3
3 3
1 2
1 3
2 3
5 2
1 2
3 5
999 0
0
 

Sample Output
1
0
2
998

AC代码:

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=1e5;
int fat[N];
int ran[N];

void init(int n)//初始化
{
    for(int i=1; i<=n; i++)
        fat[i]=i;
}
int Find(int x) //路径压缩
{
    int r=x;
    while(r!=fat[r]) //循环
        r=fat[r];
    int t=x,j;
    while(t!=r)
    {
       j=fat[t];
       fat[t]=r;
       t=j;
    }
    return r;
//    if(fat[x]==x)  递归
//        return x;
//    return Find(fat[x]);
}

void Union(int a,int b) //按秩合并
{
    int xx=Find(a),yy=Find(b);
    if(xx==yy)
        return ;
    if(ran[xx]>ran[yy])
        fat[yy]=xx;
    else
    {
        if(ran[xx]==ran[yy])
            ran[yy]++;
        fat[xx]=yy;
    }
}

int main()
{
    int n,m;
    while(cin>>n>>m)
    {
        memset(fat,0,sizeof(fat));
        memset(ran,0,sizeof(ran));
        int a,b;
        init(n);
        for(int i=1; i<=m; i++)
        {
            cin>>a>>b;
            Union(a,b);
        }
        int ans=0;
        for(int i=1; i<=n; i++)
            if(fat[i]==i)
                ans++;
        cout<<ans-1<<endl;
    }
    return 0;
}
【FPGA】DDR3调试总结 DDR3管脚根据不同的功能可以分为:数据组、地址组、控制组和电源组。如图上所示,共96个管脚。 阅读详情

相关推荐

告别轮询!用STM32CubeMX给STM32F030配置ADC多通道+DMA,实测代码分享

本文详细介绍了如何使用STM32CubeMX为STM32F030配置ADC多通道采集与DMA传输,显著提升采集效率。通过实测对比轮询与DMA模式的性能差异,提供完整的代码实现和优化技巧,帮助开发者快速掌握这一高效采集方案。

weixin_42570296的博客 409

从江湖武侠的角度来看并查集

话说江湖上散落着各式各样的大侠,有上千个之多。他们没有什么正当职业,整天背着剑在外面走来走去,碰到和自己不是一路人的,就免不了要打一架。但大侠们有一个优点就是讲义气,绝对不打自己的朋友。而且他们信奉“朋友的朋友就是我的朋友”,只要是能通过朋友关系串联起来的,不管拐了多少个弯,都认为是自己人。这样一来,江湖上就形成了一个一个的群落,通过两两之间的朋友关系串联起来。而不在同一个群落的人,无论如何都无法通过朋友关系连起来,于是就可以放心往死了打。但是两个原本互不相识的人,如何判断是否属于一个朋友圈呢?...

Fitz的博客 335

从车机到广告屏:CS5523芯片在5大显示场景的应用方案全解析

本文全面解析了CS5523芯片在车载显示、数字广告机、医疗设备和工业HMI等五大场景的应用方案。作为高性能MIPI转eDP芯片,CS5523凭借出色的兼容性和低功耗特性,成为国产替代方案的优选。文章详细介绍了芯片架构、核心技术及实际应用中的设计要点,为工程师提供全面的技术参考。

julia4scientist的博客 902

并查集原理及实现--最通俗易懂解释

江湖上散落着各式各样的大侠,有上千个之多。他们没有什么正当职业,整天背着剑在外面走来走去,碰到和自己不是一路人的,就免不了要打一架。但大侠们有一个优点就是讲义气,绝对不打自己的朋友。而且他们信奉“朋友的朋友就是我的朋友”,只要是能通过朋友关系串联起来的,不管拐了多少个弯,都认为是自己人。这样一来,江湖上就形成了一个一个的帮派,通过两两之间的朋友关系串联起来。而不在同一个帮派的人,无论如何都无法通过...

Eamon 846

物理学建模及仿真平台Chrono安装

Chrono是一个基于物理学的建模和仿真基础设施,它是在C++中实现的独立于平台的开源设计。一个projectchrono库可以嵌入到一个软件项目中,例如在可变形地形上运行的轮式和履带式车辆、机器人、机械电子系统、顺应性机构和流体固体相互作用现象。系统可以由刚性和柔性/顺应性部件组成,并带有约束、电机和接触;部件可以具有三维形状,以便进行碰撞检测。然而安装还是出现了一些问题,所以在此总结。已经装好visual studio。

Already8888的博客 6500

深入解析Lora SX1268:从基础配置到高级应用

本文深入解析了LoRa SX1268芯片从基础配置到高级应用的全过程。详细介绍了LoRa与FSK模式选择、核心参数(BW、SF、CR、LDRO)的配置策略、数据帧结构、缓冲区管理以及CAD模式等关键概念,旨在帮助开发者充分发挥SX1268在远距离、低功耗物联网通信中的潜力,并提供实用的调试技巧。

weixin_29168393的博客 116

并查集【通俗易懂】【知识点】

为了解释并查集的原理,我将举一个有爱的例子。  话说江湖上散落着各式各样的大侠,有上千个之多。他们没有什么正当职业,整天背着剑在外面走来走去,碰到和自己不是一路人的,就免不了要打一架。但大侠们有一个优点就是讲义气,绝对不打自己的朋友。而且他们信奉“朋友的朋友就是我的朋友”,只要是能通过朋友关系串联起来的,不管拐了多少个弯,都认为是自己人。这样一来,江湖上就形成了一个一个的帮派,通过两两之间的朋友...

不甘 3840

gmsv源代码c语言,石器时代ABLua的原理、简介、过程、运用、收发

操作原理(一)服务端:服务器源文件客户端:客户所操作的程序(既是游戏客户端)接口:既是某项功能(例如:鼠标点击,文字发送,战斗,观战,人物动作等)返回的值ABlua:在源代码中添加的整套引擎作为回调接口--lua所实现的功能是基于服务端源码添加的接口由该接口与客户端发送封包实现功能源码里是否有ABlua回调接口?例如:源码里的gmsv/battle.c文件(既是战斗回调文件)以下为简单描述C给予l...

weixin_35223575的博客 2408

并查集详解

并查集是我暑假从高手那里学到的一招,觉得真是太精妙的设计了。以前我无法解决的一类问题竟然可以用如此简单高效的方法搞定。不分享出来真是对不起party了。(party:我靠,关我嘛事啊?我跟你很熟么?) 来看一个实例,杭电1232畅通工程 http://acm.hdu.edu.cn/showproblem.php?pid=1232 首先在地图上给你若干个城镇,这些城镇都可以看作点,然后告诉你...

lianxiangbus 1万+

上位机1000条/秒数据不丢不卡:SQLite持久化队列最优方案实战

在上位机每秒1000条、1MB数据的场景下,SQLite做持久化队列是最优解可靠性拉满,ACID事务+WAL模式保证绝对不丢数据;性能完全够用,优化后每秒几千条没问题;轻量无依赖,只有一个.db文件;C#/.NET原生支持,代码简单易维护。只要按照上面的优化点和代码实现,完全能满足工业现场的需求,不用再担心数据丢失、存储卡采集的问题。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 482

实战案例—encrypt靶场(AES固定key篇)

AES是一种对称密钥加密方法,意味着加密和解密时使用相同的密钥。AES加密存在三种形式:AES-128、AES-192和AES-256,它们分别对应于三种不同的密钥长度——128位(即16字节)、192位(即24字节)和256位(即32字节)。通常情况下,密钥的长度越长,提供的安全性就越高,但相应地,加解密过程所需的时间也会增加。默认情况下,采用的是AES-128,其提供的安全性对于大多数应用来说已经足够充分。

zhouzhou_98的博客 497

转载-并查集详解

江湖上散落着各式各样的大侠,有上千个之多。他们没有什么正当职业,整天背着剑在外面走来走去,碰到和自己不是一路人的,就免不了要打一架。但大侠们有一个优点就是讲义气,绝对不打自己的朋友。而且他们信奉“朋友的朋友就是我的朋友”,只要是能通过朋友关系串联起来的,不管拐了多少个弯,都认为是自己人。这样一来,江湖上就形成了一个一个的帮派,通过两两之间的朋友关系串联起来。而不在同一个帮派的人,无论如何都无法通过...

whyzw1314520的博客 404

【数据集介绍】MVTec 3D AD数据集介绍

MVTec AD(MVTec Anomaly Detection)数据集是用于异常检测的计算机视觉数据集。该数据集包含来自工业生产中不同材料和产品的图像,包括玻璃、塑料、纺织品等。每个类别都包含正常样本和异常样本。这些异常样本包括各种常见的生产缺陷,如划痕、裂纹、凹陷等。MVTec AD数据集旨在帮助研究人员和从业者开发和评估用于检测工业制造中物体缺陷的算法和系统。

原来也有北瓜 7748

并查集(以hdu1232 畅通工程为例)

这也算是我学的第一个比较牛逼的算法了吧,寒假集训的时候看了一中午,结果还是只会做这种最简单。。怎么说 任重而道远啊 ,现在开始上题  题目就是 很简单的,超级简单的并查集,所谓并查集就是在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。 下面直接上代码:

wjmwsgj的博客 310

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

并查集的学习(例hdu1232畅通工程)

 并查集:(union-find sets)一种简单的用途广泛的集合. 并查集是若干个不相交集合,能够实现较快的合并和判断元素所在集合的操作,应用很多,如其求无向图的连通分量个数等。最完美的应用当属:实现Kruskar算法求最小生成树。    并查集的精髓(即它的三种操作,结合实现代码模板进行理解):1、Make_Set(x) 把每一个元素初始化为一个集合初始化后每一个元素的父亲节点是它本身,每一个元素的祖先节点也是它本身(也可以根据情况而变)。2、Find_Set(x) 查找一个元素所在的集合查找一个元素

EnjoyInwind的专栏 1987

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

并查集--学习详解 (例hdu1232畅通工程)

昨天和今天学习了并查集和trie树,并练习了三道入门题目,理解更为深刻,觉得有必要总结一下,这其中的内容定义之类的是取自网络,操作的说明解释及程序的注释部分为个人理解。    并查集学习:l         并查集:(union-find sets)一种简单的用途广泛的集合. 并查集是若干个不相交集合,能够实现较快的合并和判断元素所在集合的操作,应用很多,如其求无向图的连通分量个数等。最完美的应用当属:实现Kruskar算法求最小生成树。l         并查集的精髓(即它的三种操作,结合实现代码模板进行

xiancaifu的专栏 969

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

并查集

来看一个实例 HDU1232 首先在地图上给你若干个城镇,这些城镇都可以看作点,然后告诉你哪些对城镇之间是有道路直接相连的。最后要解决的是整幅图的连通性问题。比如随意给你两个点,让你判断它们是否连通,或者问你整幅图一共有几个连通分支,也就是被分成了几个互相独立的块。像畅通工程这题,问还需要修几条路,实质就是求有几个连通分支。如果是1个连通分支,说明整幅图上的点都连起来了,不用再修路了;如果是2个连...

Nerdant 171

并查集--hdu1232(基本模板题)

畅通工程   某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?  Input测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是城镇数目N ( 注意:两个城市之间可以有多条道路相通,

Sly_461的博客 499

hdu 1232 畅通工程(并查集)

hdu 1232 畅通工程 http://acm.hdu.edu.cn/showproblem.php?pid=1232 ProblemDescription 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需...

diansitao5461的博客 77

每日一题:畅通工程(建多少路) by python(19.9.17)

HDU_1232畅通工程: 题目描述: 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路? Input测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是城镇数目N ( < 1000 )和道...

450

第一道并差集

hdu1232 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?    Input 测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是城镇数目N ( 注意

wuhulala的休息室 1107

ACM-并查集之畅通工程——hdu1232

ACM 并查集 畅通工程 hdu1232 并查集理解

继续激情,继续奋斗。 7733

【并查集】HDU 1232 畅通工程

HDU 1232 畅通工程 #include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <cmath> #include <cstring> #include <string> #include <v...

L_X_ 134

hdu 1232 畅通工程

hdu 1232 畅通工程题意题解源代码 传送门 题意 给定n个村子,和村子之间的道路,求连接所有的村子至少需要再修多少条道路 题解 互相连通的村子可以看成一个集合,一个点,现在需要求把这这些集合(点)连接起来 需要多少条线,由树的概念就可以看出来,边数等于点数-1,相当于求集合的数目, 可以用并查集解决 源代码 #include<cstdio> const int maxn = ...

antRain的博客 166

并查集入门(hdu1232“畅通工程”)

在学习并查集之前,首先需要明白基本的并查集可以完成的功能。并查集主要是用于处理不相交集合的合并问题。它是一种基础算法,在离散数学中,可以利用并查集求一个图的连通分支,利用其这个特性可以为我们解决一系列的问题,例如hdu1232"畅通工程"等等。在这里便利用这道题理解并查集的基本知识。 在讲解题目之前,先了解一下并查集。并查集就是将一系列的元素根据题中所给的相关关系,将它们分成一个个互不...

awli5131的博客 245

HDU1232畅通工程 POJ1611 嫌犯 并查集问题(c/c++实现)

HDU1232畅通工程 题目概述: http://acm.hdu.edu.cn/showproblem.php?pid=1232 并查集模板: #define N 9999 int f[N];//存放当前下表位置的父亲 void init(int n){ //初始化每个人的爸爸为自己 for(int i=0;i<n;i++){ f[i]=i; } return; } int Fin...

我要夺回那失落的荣光 364
上一篇: 给你N个数求其最小公倍数(hdu 1019 Least Common Multiple)
下一篇: Codeforces Round #449 (Div. 2) B. Chtholly's request
Puppet__
博客等级 码龄9年 319粉丝 328原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值