• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

zsl2002

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

团伙

题目描述

现在有 nn 个人,他们之间有两种关系:朋友和敌人。我们知道:

  • 一个人的朋友的朋友是朋友
  • 一个人的敌人的敌人是朋友

现在要对这些人进行组团。两个人在一个团体内当且仅当这两个人是朋友。请求出这些人中最多可能有的团体数。

输入格式

第一行输入一个整数 nn 代表人数。

第二行输入一个整数 mm 表示接下来要列出 mm 个关系。

接下来 m 行,每行一个字符 opt 和两个整数 p,q,分别代表关系(朋友或敌人),有关系的两个人之中的第一个人和第二个人。其中 opt 有两种可能:

  • 如果 opt 为 F,则表明 p 和 q 是朋友。
  • 如果 opt 为 E,则表明 p 和 q 是敌人。

输出格式

一行一个整数代表最多的团体数。

输入输出样例

输入
4
E 1 4
F 3 5
F 4 6
E 1 2
输出
   3
 
 

思路:本题使用并查集的思路解法,将a定义为a的朋友,a+n定义为a的敌人,接下来简单的分类讨论,如果a和b是朋友,那么将a和b的朋友相连即可,如果a和b是敌人,将a的敌人和b的朋友相连,a的朋友与b的敌人相连即可。


 

 

代码:

#include<bits/stdc++.h>
using namespace std;

const int N = 2005;
int pre[N];
int n, m, r;

int find(int k)
{
if (pre[k] == k) return k;
return pre[k] = find(pre[k]);
}

int main()
{
cin >> n >> m;
for (int i = 1; i <= n << 1; i=i+1) pre[i] = i;
while (m--)
{
char op; int x, y;
cin >> op >> x >> y;
if (op == 'F') pre[find(x)] = find(y);
else pre[find(x + n)] = find(y), pre[find(y + n)] = find(x);
}
for (int i = 1; i <= n; i=i+1)
if (pre[i] == i) r++;
cout << r << endl;
return 0;
}

 

 

 

 

 

 

重难点主要就是考察并查集的使用。

 

posted on 2022-06-26 16:00  星河2002  阅读(36)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3