算法竞赛入门经典例题-并查集

来源:互联网 发布:esp8266单片机51程序 编辑:程序博客网 时间:2024/05/29 19:09

*

例题5:有一些化合物,每个化合物都由两种元素组成的(每个元素用一个大写字母表示)。你是一个装箱的工人,从实验员那里按照顺序依次把一些简单化合物装到车上。但这里存在一个安全隐患:如果车上存在k个简单的化合物,正好包含k中元素,那么它们将组成一个易爆的混合物。为了安全起见,每当你拿到一个化合物时,如果它和已装的化合物形成易爆混合物,你就应当拒绝装车;否则就应该装车。变成输出有多少个没有装车的化合物。

*

*分析:典型的并查集,每一个物品合一看成一个独立的顶点,则一个简单化合物就是一条边,如果两个顶点x,y联通则说明有危险,所以可以用一个并查集来维护图的联通分量集合,并查集的详解有一篇写的很易懂的博客并查集详解,看完之后觉得别具一格,推荐给正在学习并查集的ACER们。

并查集主要是由保存上级的数组pre[],Find()函数,Join()函数进行实现,Find函数是用来查找元素的根节点,join函数用来连接两个节点,将联通分量合并为一个。

而在此题中,只需要使用Find函数查找两个元素x,y是否在同一个集合中,也就是时候构成了一种化合物, 并不用用到join函数进行合并。
*

代码:

#include<cstdio>const int maxn=100000+10;int pa[maxn];//判断两个元素是否属于一个联通分量,看是否有共同的根节点。int Find(int x){//意思是pa[x]和x相等代表x就已经是根节点了,不相等就继续查找根节点,找到了就返回。    return pa[x]!=x?pa[x]=find(pa[x]):x;}int main(){    int x,y;    while(scanf("%d",&x)==1){    for(int i=0;i<=maxn;i++)        pa[i]=i;   //先让每个元素成为自己的根节点,初始化Pa数组    int resusals=0;    while(x!=-1){       scanf("%d",&y);       x=Find(x);       y=Find(y);       if(x==y)       ++refusals;       else       pa[x]=y;       scanf("%d",&x);    }    printf("%d\n",refusals);    }    return 0;}

刚开始看白书的数据结构部分,虽然有些内容很难懂,但是看会了就都是规律~~

0 0
原创粉丝点击