团伙(Group)

线上OJ:

1385:团伙(group)

核心思想:

1、朋友的朋友就是朋友。这句话意味着朋友之间直接合并

2、敌人的敌人就是朋友。这句话说明,如果 a 和 b 是敌人,a 和 c 也是敌人,则 c 和 b 就是朋友。如果 a 和 d 也是敌人,则 d 和 {c, b} 都是朋友。

2.1 所以当 a 和 x 是敌人时,xa 的敌人 合并即可。用一个数组 a[i] 记录第 i 个人的敌人(只需记录一个即可,因为合并时会合并他们的根节点)。

2.2 如果 a 和 x 是敌人,但 a[i] 数组为空,则把 x 赋值给 a[i],作为它的第一个敌人。

3、最后判断有几个团伙时,只要数下有几个根即可(p[i]==i 的为根)。

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

using namespace std;

int p[1010], enemy[1010] = {0}, n, m, x, y, k;

int find(int x)  // 查询x所在集合中的根节点
{
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}

void unionn(int x, int y)  // 合并x和y
{
    int a = find(x), b = find(y);
    if (a != b) p[a] = b;
}

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i ++ )  p[i] = i;  // 初始化每个元素的根节点为自己
    for (int i = 1; i <= m; i ++ )
    {
        scanf("%d%d%d", &k, &x, &y);
        if (k == 0)
            unionn(x, y);  // 如果两个人是朋友,直接合并
        else if (k == 1)
        {
            if(!enemy[x])
                enemy[x] = y;  // 如果x还没有敌人,则赋值y为x的敌人
            else
                unionn(enemy[x], y);  // 如果x已经有敌人,则把y合并到x的敌人群里(敌人的敌人就是朋友)

            if(!enemy[y])  // 反之亦然
                enemy[y] = x;
            else
                unionn(enemy[y], x);
        }
    }

    int ans = 0;
    for(int i = 1; i <= n; i++)
        if(p[i] == i)  ans++;   // 满足p[i] == i的说明是根。根的数量就要是团伙的数量

    printf("%d\n", ans);
}

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值