hdu 1182 A Bug's Life 并查集

题目链接 

                 https://cn.vjudge.net/contest/244467#problem/J

题目大意

                 每次输入两个昆虫发生性行为(正常是互为异性), 判断是否存在同性恋

题目分析

                看到这个题目就想到和之前做的题目 犯罪团伙( Find Them, Catch Them!)    很相似,  然后试着用同样的方法写,

                然后就过了. 主要分为两个种类, 我把异性的看成敌人, 同性的看成朋友, 男的和女的分别存在两个不同的集合

                (不需要知道哪个集合是男的,哪个集合是女的, 只要知道两个集合是对立的就好).

 

                正如我写的这边文章 https://blog.csdn.net/Mr_HCW/article/details/81484042 (犯罪团伙题解)

                我把两个性别看成两大帮派, 每次输入的两个编号视为敌人(异性) Ps:只限前两组一定是敌人, 从第三组开始可能是敌人,

                可能是朋友.而我们就是要判断当前两个编号是否为朋友, 朋友(同性)之间是不能发生性关系的.

               

             然后根据敌人的敌人就是朋友, 就AC了,详细请看 https://blog.csdn.net/Mr_HCW/article/details/81484042 (犯罪团伙题解)

                

           然后注意的是 最后输出的时候要加上两个换行(endl) ,  第一遍提交时没意思到,导致格式错误

          

 代码

#include<iostream>
#include<cstdio>
using namespace std;
const int MAX = (int)2e3 + 5;
int per[MAX],enemy[MAX];

int find(int x)
{
	int r=x;
	while (r != per[r])
		r = per[r];
	int i = x, j;
	while (i != r)
	{
		j = per[i];
		per[i] = r;
		i = j;
	}
	return r;
}
void join(int x, int y)
{
	int fx = find(x), fy = find(y);
	if (fx != fy)
		per[fx] = fy;
}
int main()
{
	int t,  k = 1;
	cin >> t;
	while (t--)
	{
		int n, m, res = 0;
		scanf("%d%d", &n, &m);
		for (int i = 1; i <= n; i++)
		{
			per[i] = i;
			enemy[i] = 0;
		}
		while (m--)
		{
			int a, b;
			scanf("%d%d", &a, &b);
			if (enemy[a] == 0 && enemy[b] == 0)
			{
				enemy[a] = b;
				enemy[b] = a;
			}
			else if (enemy[a] == 0)
			{
				enemy[a] = b;
				join(a, enemy[b]);
			}
			else if (enemy[b] == 0)
			{
				enemy[b] = a;
				join(b, enemy[a]);
			}
			else
			{
				if (find(a) == find(b)) res = 1;
				else
				{
					join(a, enemy[b]);
					join(b, enemy[a]);
				}
			}
		}
		printf("Scenario #%d:\n", k++);
		if (res == 1)
			cout << "Suspicious bugs found!" << endl<<endl;
		else
			cout << "No suspicious bugs found!" << endl << endl;
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值