团伙(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;
} 
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
并查集是一种数据结构,可以有效地解决团伙问题。团伙问题指的是在一个群体中,找出其中的团伙关系。举个例子,假设有一群人,其中有些人是朋友,有些人是陌生人,现在需要找出所有的朋友团伙。这个问题可以用并查集来解决。 具体实现过程如下: 1. 初始化并查集,将每个人看作一个单独的团伙,即每个人的父节点都是自己。 2. 遍历所有的朋友关系,将每个朋友关系所在的两个人合并到同一个团伙中。合并的过程中,需要找到两个人所在团伙的根节点,将其中一个根节点的父节点指向另一个根节点。 3. 遍历所有的人,统计每个团伙的人数。具体方法是遍历每个人,找到该人所在团伙的根节点,然后统计该根节点下所有子节点的个数。 4. 输出所有团伙的人数。 下面是并查集实现团伙问题的示例代码(假设已经读入了朋友关系列表friend_list): ```python # 初始化并查集 parent = {} for i in range(len(friend_list)): parent[i] = i # 合并朋友关系所在的团伙 for f1, f2 in friend_list: root1 = find_root(parent, f1) root2 = find_root(parent, f2) if root1 != root2: parent[root1] = root2 # 统计每个团伙的人数 group_sizes = {} for i in range(len(friend_list)): root = find_root(parent, i) if root not in group_sizes: group_sizes[root] = 1 else: group_sizes[root] += 1 # 输出每个团伙的人数 for root, size in group_sizes.items(): print("团伙{}有{}个人".format(root, size)) # 找到节点的根节点 def find_root(parent, node): while parent[node] != node: node = parent[node] return node ``` 这个代码实现了一个简单的并查集,并可以用来解决团伙问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

柠檬ya

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

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

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

打赏作者

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

抵扣说明:

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

余额充值