七星瓢虫:
今天搞了一个七星瓢虫的题:(这是个并查集的题)
题目:
有七星瓢虫n个,可以俩俩交配m组( 0<n<=2000, 0<m<=1000000)
如果俩个交配为同性则输出:Suspicious bugs found!
没有则输出:No suspicious bugs found!
输入:
第一行输入t ,表示t个用例
接下来第一行输入n m后m行输入a b,代表a和b交配。
输出:每一组输出一个:Scenario #1:然后输出判断好的是否为同性交配。
这个题开始想到好像可以不用并查集,给个数组,将下标为a的值为1代表a的性别,下标为b的值为2代表b的性别,然后后面输入的判断是否性别一样就可以了,后面仔细想想,确实不行。然后需要用到并查集的知识来做该题,只要将俩种性别的全部绑在一个树上面就行了。可是这又有个弊端,如果我第一对输入1 2,第二对输入3 4,我该怎么判断1和3是不是一种性别。然后看了博客,可以用这种写法:将数组定义俩倍大,后面的n个代表是前面n个相反性别的瓢虫,然后将所有性别相同的瓢虫全部聚集在一棵树上就行了,判断是不是一个性别的俩个瓢虫就做出来了。下面是代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#define ll long long
using namespace std;
int a[4040];
int fun(int n)//查看瓢虫的在哪棵树上面
{
int m=n;
while(n!=a[n])n=a[n];
a[m]=n;
return n;
}
int brfun(int x,int y)//将俩个一样的瓢虫放到一棵树上面
{
int p=fun(x),q=fun(y);
if(p!=q)a[p]=q;
}
int main()
{
int t,k=1;
cin >> t;
while(t--)
{
int n,m,f=0;
cin >> n >> m;
for(int i=0;i<=n*2;i++)a[i]=i;
for(int i=0;i<m;i++)
{
int x,y;
cin >> x >> y;
if(f==0)
{
int p=fun(x),q=fun(y);
if(p==q)//在同一棵树上面的瓢虫就是一样的性别
{
f=1;
continue;
}
else
{
brfun(x,y+n);//y+n就是y性别的相反。
brfun(x+n,y);//x+n就是x性别的相反。
}
}
}
printf("Scenario #%d:\n",k++);
if(f)printf("Suspicious bugs found!\n");
else printf("No suspicious bugs found!\n");
printf("\n");
}
return 0;
}