T241093 团伙

题目描述

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

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

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

输入格式

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

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

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

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

输出格式

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

输入输出样例

输入 #1复制

6

4

E 1 4

F 3 5

F 4 6

E 1 2

输出 #1复制

3

 

#include<iostream>

#include<cstdio>

using namespace std;

int father[1005],f[1005][1005];  //f数组判断是否是敌人

int find(int x) //递归

 {

if(father[x]!=x) father[x]=find(father[x]); //优化

return father[x];//如果自己不是父亲结点,那么寻找父亲结点

}

void uni(int x,int y)//合并

{

int r1=find(x);

int r2=find(y);

if(r1!=r2)

{

father[r2]=r1; //使r2的父亲结点是r1;

}

}int main(){

int n,m;

cin>>n>>m;

for(int i=1;i<=n;i++)

{

father[i]=i; //初始化,即开始前,每个数都是单独存在的,即每个数的父亲结点都是自己

}

for(int i=1;i<=m;i++)

{

char p;

int x,y;

cin>>p>>x>>y;

if(p=='F') uni(x,y);//如果是朋友就直接合并

else

{

f[x][y]=f[y][x]=1;//用来判断xy是否是敌人

for(int i=1;i<=n;i++)//把所有人都列出来,看看是不是x或者y的敌人

{

if(f[x][i]) uni(i,y);// 如果x和i是敌人,x又和y是敌人,那么i和y是朋友合并

if(f[y][i]) uni(i,x); 

}

}

}

int ans=0;//统计数目

for(int i=1;i<=n;i++)

{

if(father[i]==i)//如果父亲结点是自己,那么就是一个团队

{

ans++;

}

}

cout<<ans;

}

posted @   xh小小孩  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示