1.题目
http://acm.hdu.edu.cn/showproblem.php?pid=1829
2.分析
第一、题目大意:就是检查一堆数据中是否有同性恋,找出主要矛盾是如果1喜欢2,2喜欢3,而1又喜欢3,则矛盾,即找出出现类的的矛盾。
第二、通过记录本节点到根节点的步长推断和根节点性别的关系:距离根节点步长为奇数表明和根节点性别相反;距离根节点步长为偶数表明和根节点性别相同;
第三、
(1)当r1和r2的根节点相同,则直接根据二者各自到根节点的步长判断性别是否相同;
(2)当r1和r2的根节点不相同,首先需要合并二者所在的集合;然后修正r1所在集合的根节点到r2所在集合根节点的步长(此时需要根绝r1和r2的性别关系判断二者根节点的性别关系)。由于r1所在集合根节点步长初始值发生改变,所以需要更新r1所在集合所有节点到根节点的步长(留在下一次查询的时候更新)
3.复杂度
空间复杂度为O(N),建立一个集合的时间复杂度为O(1),N次合并M次查找的时间复杂度为O(MAlpha(N)),这里Alpha是Ackerman函数的某个反函数,在很大的范围内(人类目前观测到的宇宙范围估算有10的80次方个原子,这小于前面所说的范围)这个函数的值可以看成是不大于4的,所以并查集的操作可以看做是线性的。
4.涉及内容
数据结构:并查集
5.感想
是一道并查集好题。不过英文不好导致题意有些难懂,在思考的时候只是想到了需要根据到达根节点的步长来计算性别关系,没有考虑集合合并对每个集合中元素到达合并后集合根节点的步长计算公式。
6.代码
#include <stdio.h>
#include <stdlib.h>
typedef struct Node1829
{
int parent,step;
} Node1829;
Node1829 parent1829[2005];//记录个数
void makeset1829()
{
for(int i=0;i<2005;++i)
parent1829[i].parent=-1,parent1829[i].step=0;
}
int find1829(int x)
{
if(parent1829[x].parent>0)
{
int y=find1829(parent1829[x].parent);
parent1829[x].step=parent1829[x].step+parent1829[parent1829[x].parent].step;//更新,因为可能存在两个树的合并导致本集合的根的step改变,所需要重新就算
parent1829[x].parent=y;
return y;
}
return x;
}
bool union1829(int r1, int r2) {
int a=find1829(r1);
int b=find1829(r2);
if( a == b)
{
if((parent1829[r1].step-parent1829[r2].step)%2==0)
return true;
return false;
}
parent1829[a].parent=b;
parent1829[a].step=parent1829[r1].step+parent1829[r2].step+1;//在合并集合的时候,需要根据r1和r2的性别关系来推断r1的父节点a与r1的父节点b的关系
return false;
}
int main()
{
long N,M,k=0,t;int a,b;
scanf("%ld",&t);
while(t--)
{
scanf("%ld %ld",&N,&M);
makeset1829();
bool flag=false;
for(long i=0;i<M;++i)
{
scanf("%d %d",&a,&b);
if(union1829(a,b))
flag=true;
}
if(flag)
printf("Scenario #%ld:\nSuspicious bugs found!\n\n",++k);
else
printf("Scenario #%ld:\nNo suspicious bugs found!\n\n",++k);
}
return 0;
}
7.参考文献
http://www.cnblogs.com/Shirlies/archive/2012/03/05/2380144.html (并查集父节点初始为自身)
http://www.cnblogs.com/newpanderking/archive/2012/10/12/2721799.html (和上一个类似)
http://blog.csdn.net/ice_crazy/article/details/7751756 (新思路,每录入一对关系就更新整体,因此存的就是结果)
http://blog.csdn.net/xingyeyongheng/article/details/8813524 和上一个类似的思路