并查集   英文: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. net_device 结构体分析

    /* * The DEVICE structure. * Actually, this whole structure is a big mistake. It mixes I/O * data wi ...

  2. python数据结构与算法——图的广度优先和深度优先的算法

    根据维基百科的伪代码实现: 广度优先BFS: 使用队列,集合 标记初始结点已被发现,放入队列 每次循环从队列弹出一个结点 将该节点的所有相连结点放入队列,并标记已被发现 通过队列,将迷宫路口所有的门打 ...

  3. 2015.12.21~2015.12.24真题回顾!-- HTML5学堂

    2015.12.21~2015.12.24真题回顾!-- HTML5学堂 山不在高,有仙则名!水不在深,有龙则灵!千里冰封,非一日之寒!IT之路,须厚积薄发!一日一小练,功成不是梦!小小技巧,尽在HT ...

  4. unity, terrain道出为obj

    http://wiki.unity3d.com/index.php?title=TerrainObjExporter

  5. [轉]Android Libraries 介紹 - Butter knife

    原文地址 Butter Knife 簡介 Butter Knife - Field and method binding for Android views.助你簡化程式碼,方便閱讀. 使用方法 開發 ...

  6. Reflector 反编译 .NET文件后修复

    反编译后的工程文件用VS2010打开后,在打开窗体时会出现一系列错误提示: 第一种情况: “设计器无法处理第 152 行的代码: base.AutoScaleMode = AutoScaleMode. ...

  7. Junit4常用注解

    Junit4注解 JUnit4的测试类不用再继承TestCase类了.使用注解会方便很多. @Before:初始化方法@After:释放资源@Test:测试方法,在这里可以测试期望异常和超时时间@Ig ...

  8. json格式的数组长度

    var data = [{"id":"1","name":"a"},{"id":"2&qu ...

  9. eclipse 清楚git记录的密码

    菜单:window->preferences弹出上述对话框

  10. 65. Reverse Integer && Palindrome Number

    Reverse Integer Reverse digits of an integer. Example1: x =  123, return  321 Example2: x = -123, re ...