并查集   英文:Disjoint Set,即“不相交集合”

将编号分别为1…N的N个对象划分为不相交集合,

在每个集合中,选择其中某个元素代表所在集合。

常见两种操作:

n       合并两个集合

n       查找某元素属于哪个集合

并查集实现的程序代码:

int set[MAXN],rank[MAXN]; //set[i]=k表示i的父节点是k,rank[]存储树的深度。

int FindSet(int x)

{

if(set[x]!=x)

set[x]=FindSet(set[x]);

return set[x];

}//寻找x的根节点

void MakeSet(int x)

{

set[x]=x;

rank[x]=1;

}//初始化,各节点都是孤立的

void Link(int a,int b)

{  //合并时判段rank[a],rank[b]的大小,以减小树的高度

if(rank[a]>rank[b])

set[b]=a;

else if(rank[a]<rank[b])

set[a]=b;

else

{

set[a]=b;

rank[b]++;

}

}

void Union(int a,int b)

{

Link(FindSet(a),FindSet(b));

}

Find的时间复杂度取决于树的高度.在实际中,由于多次Union操作,容易导致树的高度越来越大,

从而降低Find的执行效率. 实际上在并查集中,树的具体结构并不重要,只要维持树所包含的结点不变即可

HDOJ 1856

http://acm.hdu.edu.cn/showproblem.php?pid=1856

题目大意:朋友在一个集合,朋友的朋友也是朋友,求元素最多的集合的元素个数。

贴代码:

 #include <stdio.h>
int set[];
int rank[]; //这里的rank[]和模板不同,rank[i]=k表示以i为根节点树的节点个数,
//即集合里元素的个数 int max=;
int find(int x)
{
if(set[x]!=x)
set[x]=find(set[x]);
return set[x];
} void merge(int a,int b)
{
int fx=find(a);
int fy=find(b);
if(fx==fy)
return ;
if(rank[fx]>rank[fy])
{
set[fy]=fx;
rank[fx]=rank[fy]+rank[fx];
if(rank[fx]>max)
max=rank[fx];
}
else
{
set[fx]=fy;
rank[fy]=rank[fy]+rank[fx];
if(rank[fy]>max)
max=rank[fy];
}
} int main()
{
int n,i,a[],b[];
while(scanf("%d",&n)!=EOF)
{
if(n==)
{
printf("1\n"); //没有关系时,各点孤立,所有集合里都只有一个元素
continue;
}
for(i=;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
set[a[i]]=a[i];
set[b[i]]=b[i]; //输入的整数对的所有数,不一定的连续的,不能1~2*n遍历
rank[a[i]]=rank[b[i]]=;
}
max=;
for(i=;i<=n;i++)
{
merge(a[i],b[i]);
}
printf("%d\n",max);
}
return ;
}

并查集(HDOJ 1856)的更多相关文章

  1. 并查集 HDOJ 1232 畅通工程

    题目传送门 /* 并查集(Union-Find)裸题 并查集三个函数:初始化Init,寻找根节点Find,连通Union 考察:连通边数问题 */ #include <cstdio> #i ...

  2. 并查集 HDOJ 5441 Travel

    题目传送门 题意:给一张无向图,问存在多少(a, b)表示a点到b点经过的边值小于等于x ((a,b) 和 (b, a)属于不同的方案) 分析:首先将边权值和查询x值升序排序,从前往后扫描边,累加从u ...

  3. 关于 图论·并查集·HDU1232&1856

    其核心是追溯其根数和链接两个数,而HDU 1856要多一步,每一个根数要标记自己和自己子数的个数,因此用结构体.注意:1856 用C写没超时,用C++写超时了╮(╯﹏╰)╭ 接下来是题目和代码: 畅通 ...

  4. 简单并查集 -- HDU 1232 UVALA 3644 HDU 1856

    并查集模板: #include<iostream> using namespace std; ],x,y; ]; //初始化 x 集合 void init(int n) { ; i< ...

  5. HDOJ并查集题目 HDOJ 1213 HDOJ 1242

    Problem Description Today is Ignatius' birthday. He invites a lot of friends. Now it's dinner time. ...

  6. HDU(1856),裸的带权并查集

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1856 题意:朋友圈问题,A和B是朋友,B和C是朋友则A和C也是朋友,依次类推,题目的意思就是求最大的朋 ...

  7. HDU 1856 More is better(并查集+离散化)

    题目地址:HDU 1856 水题.因为标号范围太大,而数据数仅仅有10w,所以要先进行离散化.然后就是裸的并查集了. 代码例如以下: #include <iostream> #includ ...

  8. HDU 1856 并查集

    http://acm.hdu.edu.cn/showproblem.php?pid=1856 More is better Time Limit: 5000/1000 MS (Java/Others) ...

  9. hdoj 1116 Play on Words 【并查集】+【欧拉路】

    Play on Words Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T ...

随机推荐

  1. 收集的maven 仓库地址(maven repository)

    maven 仓库地址: 共有的仓库http://repo1.maven.org/maven2/http://repository.jboss.com/maven2/http://repository. ...

  2. [原创] 用两个queue实现stack的功能

    #include <iostream> #include <queue> using namespace std; template <class T> class ...

  3. 网页闯关游戏(riddle webgame)--游戏玩法和整体介绍

    前言: 记得上大学那会, 有位传说中的大牛, 写了一个网页闯关类的游戏. 当时我们玩得不亦乐乎, 也是第一次接触到这种形式的游戏. 不过当时纯玩家心态, 并没有想过去创造一个. 最近想起这事, 突然想 ...

  4. C语言编译和链接过程

    1.程序的编译  一般而言,大多数编译系统都提供编译驱动程序(complier driver),根据用户需求调用语言预处理器,编译器,汇编器和链接器.例如有如下历程://main.c void swa ...

  5. 排序算法总结(四)快速排序【QUICK SORT】

    感觉自己这几篇都是主要参考的Wikipedia上的,快排就更加是了....wiki上的快排挺清晰并且容易理解的,需要注意的地方我也添加上了注释,大家可以直接看代码.需要注意的是,wikipedia上快 ...

  6. protobuf 数据解析的2种方法

    方法1: message person{required int32 age = 1;required int32 userid = 2;optional string name = 3;} mess ...

  7. express创建项目

    sudo apt-get install node-express-generator dave@voctrals:~/WebstormProjects/nodejs-study/express$ e ...

  8. nodejs项目在webstorm里进行debug的设定

    菜单 > Run > Edit Configurations... 菜单 > Run > Debug... 菜单 > Run > Edit Configuratio ...

  9. LVS-DR工作原理图文详解

    为了阐述方便,我根据官方原理图另外制作了一幅图,如下图所示:VS/DR的体系结构: 我将结合这幅原理图及具体的实例来讲解一下LVS-DR的原理,包括数据包.数据帧的走向和转换过程. 官方的原理说明:D ...

  10. 2015年10月TIOBE编程语言排行榜

    名副其实的月经贴.