本文主要是介绍hdu 1829 A Bug's Life 并查集(囧),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
这种用并查集判段是否有同性恋的还是第一次做,并查集的功能也太强大了吧。。囧。。
还是说说思路吧;
就是把这些关系分成两个集合中,同性和异性的,给出的一对数中只要在同一个集合,则他们一定是同性恋;
那么该怎样分成两个集合呢?
下面咱就详细说说过程吧;
这里要用到一个next数组,它记录的是恋人之间的关系:
next【i】=j,就表示i的恋人是j了;
如果next【i】==0,则此时的恋人关系可以确定next【i】=j。
如果next【i】不等于零,则next记录的一定是他的上一个恋人,则next【i】和j是同性关系了,则此时便可以next【i】和j合并到一个数组中了。。
判段next时,一定要注意对i,j都判断。即如果next【i】==0;时next【i】=j,同时判段next【j】与0的关系来确定是否进行合并。。
到此这题就可以结束了。。
至此我们知道了并查集不仅可以判段,所给出点的关系中会有几个集合,每个集合有几种元素。
他还可以确定是否会出现同性恋的问题;
啰嗦了这么多就是想更好地掌握并查集的用法来解决更多的实际问题。。
#include"stdio.h"
#include"string.h"
int pre[3000],next[3000000];
int find(int k)
{
if(k!=pre[k])
pre[k]=find(pre[k]);
return pre[k];
}
void Union(int x,int y)
{
x=find(x);
y=find(y);
if(x!=y)
pre[y]=x;
}
int main()
{
int m,n,i,j=1,k,p,t;
scanf("%d",&k);
while(k--)
{
scanf("%d%d",&m,&n);
for(i=1;i<=m;i++)
pre[i]=i;
memset(next,0,sizeof(next));
int flag=0;
for(i=0;i<n;i++)
{
scanf("%d%d",&p,&t);
if(find(p)==find(t))
flag=1;
else
{
if(next[p]==0)
next[p]=t;
else
{
Union(next[p],t);
}
if(next[t]==0)
next[t]=p;
else
{
Union(next[t],p);
}
}
}
printf("Scenario #%d:\n",j++);
if(flag)
printf("Suspicious bugs found!\n\n");
else
printf("No suspicious bugs found!\n\n");
}
return 0;
}
这篇关于hdu 1829 A Bug's Life 并查集(囧)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!