这题除了用并查集之外,还可以DFS、BFS、二分图过!
并查集:
题意:
首先给定n只虫子,然后给出m个情况。每个情况给出两只虫子交配,当出现两只虫子为同性恋时,便判错。
解题思路:
首先肯定是并查集,将同一类的虫子并到同一个集合。
我刚开始的时候想把所以有关系的虫子并到一个集合,然后通过其到根节点的步数来判断。结果wa了。。
后来学长指点,将虫子分为两个集合,一个为共,一个为母。
如果两字虫子的父节点为同一个,则为同性恋。
如果两只虫子都没有标记过,则将两只虫子分别归为到不同的性别。
首先给定n只虫子,然后给出m个情况。每个情况给出两只虫子交配,当出现两只虫子为同性恋时,便判错。
解题思路:
首先肯定是并查集,将同一类的虫子并到同一个集合。
我刚开始的时候想把所以有关系的虫子并到一个集合,然后通过其到根节点的步数来判断。结果wa了。。
后来学长指点,将虫子分为两个集合,一个为共,一个为母。
如果两字虫子的父节点为同一个,则为同性恋。
如果两只虫子都没有标记过,则将两只虫子分别归为到不同的性别。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f[2005],sex[2005],r[2005];
int find(int x)
{
if (x!=f[x])
f[x]=find(f[x]);
return f[x];
}
void uni(int x,int y)
{
x=find(x);
y=find(y);
if (x==y) return;
else if (r[x]>r[y])
f[y]=x;
else if (r[x]==r[y])
{
r[x]++;
f[y]=x;
}
else
f[x]=y;
}
int main ()
{
int t,n,m,i,a,b,p=1;
cin>>t;
while(t--)
{
bool ass=true;
scanf("%d%d",&n,&m);
memset(f,0,sizeof(f));
memset(sex,0,sizeof(sex));
memset(r,0,sizeof(r));
for (i=1; i<=n; i++)
f[i]=i;
for (i=1; i<=m; i++)
{
scanf("%d%d",&a,&b);
if (ass)
{
if (find(a)==find(b))
ass=false;
else
{
if (!sex[a])
sex[a]=b; //如果a没有被标记过,则使a的异性为b
else
uni(sex[a],b); //否则,将a的父节点和b连接
if (!sex[b])
sex[b]=a;
else
uni(sex[b],a);
}
}
}
if (!ass)
printf("Scenario #%d:\nSuspicious bugs found!\n",p);
else
printf("Scenario #%d:\nNo suspicious bugs found!\n",p);
p++;
cout<<endl;
}
return 0;
}
转载自: http://blog.youkuaiyun.com/sio__five/article/details/8813764