团伙(group)

团伙(group)

Description

在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足:

1、我朋友的朋友是我的朋友;

2、我敌人的敌人是我的朋友;

所有是朋友的人组成一个团伙。告诉你关于这n个人的m条信息,即某两个人是朋友, 或者某两个人是敌人,请你编写一个程序,计算出这个城市最多可能有多少个团伙?

Input

第1行为n和m,1<n<1000,1<=m<=100 000;

以下m行,每行为p x y,p的值为0或1,p为0时,表示x和y是朋友,p为1时, 表示x和y是敌人。

Output

一个整数,表示这n个人最多可能有几个团伙。

Sample Input 1

6 4
1 1 4
0 3 5
0 4 6
1 1 2

Sample Output 1

3

注意题目里的两句话:朋友的朋友是朋友,敌人的敌人是朋友,当p为1时表示x,y是敌人,那么很显然,x的敌人和y就是朋友,y的敌人和x也是朋友,这里用一个数组a来记录x,y的敌人,然后使用并查集的思想找他们的祖先,具体的看下面的代码

代码:
#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e5+5;
int pp[maxn],a[maxn]; //pp数组用来存储父节点,a数组用来存储x,y的敌人
int m,n;
int p,x,y;


int find(int x)	//查找函数+路径压缩
{
	return x == pp[x] ? x : pp[x] = find(pp[x]);
}

int main()
{
	cin >> n >> m;
	for(int i = 1 ; i <= n*2 ; i++)
		pp[i] = i;
	for(int i = 0 ; i < m ; i++)
	{
		cin >> p >> x >> y;
		int r1 = find(x);	//找到r1的祖先
		int r2 = find(y);	//找到r2的祖先
		if(!p)				//如果p为0,说明x,y是朋友,那么r1和r2自然也是朋友
		{
			pp[r2] = r1;	//所以让r2的父节点为r1
		}
		else
		{
			if(!a[x])	//如果a[x]为0,就说明x没有敌人,那y就是x的敌人
				a[x] = y;
			else		//如果a[x]不为零,说明x的敌人为a[x],那么找到a[x]的父节点,其父节点是y的朋友,所以让r3的父节点为r2
			{
				int r3 = find(a[x]);
				pp[r3] = r2;			
			}
			if(!a[y])			//这里和上面一样,不多赘述
				a[y] = x;
			else
			{
				int r3 = find(a[y]);
				pp[r3] = r1;
			}
		}
	}
	int cnt = 0;
	for(int i = 1 ; i <= n ; i++)//最后只要判断一下结点指向自身的有多少个即可
	{
		if(pp[i] == i)
			cnt++;
	}
	cout << cnt << endl;
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柠檬ya

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值