【数据结构 | C++】群聊chat

在某聊天软件中,共有n个用户,m个群。如果两个用户A、B之间想要交流的话,只能通过消息链A→user1→user2→…→B进行交流,如果A、B在同一个群里的话,可以直接交流。如果A、B不在同一个群里的话,可以通过若干个中间人进行交流。

现在给出每个用户已经加入的群列表,问这n个用户总共最少还需要再加多少次群,才能使得任意两个用户之间可以进行交流。

输入格式:第一行为两个正整数n和m,表示用户数量和群数量。接下来n行,每行第一个整数为k_i,表示第i个用户所加入的群数量。紧接着k_i个正整数,表示第i个用户加入的群编号(编号从1开始)。

输出格式:输出一个整数,表示这n个用户总共最少还需加群的次数。

#include <bits/stdc++.h>
using namespace std;
int root[100005];
int find(int x){
	if(x==root[x])return x;
    else return root[x]=find(root[x]);
}
int main(){
	int n,m;cin>>n>>m;int t[1000];//表示每个群是否被访问过 
	for(int i=1;i<=m;i++)t[i]=0;//初始化
	int not_all_zero=0,num=0;
	for(int i=0;i<n;i++){
		int k;cin>>k;//用户加入的群数量 
		if(k==0){
			num++;continue;
		}else{
		not_all_zero=1;//至少一个用户加群
		}
		int b;cin>>b;//第一个群编号 
		if(t[b]==0){
			t[b]=1;root[b]=b;//初始化群的父节点 
		}
		for(int i=2;i<=k;i++){
			int a;cin>>a;//剩下的k-1个群编号
			if(t[a]==0){
				t[a]=1;root[a]=a;//初始化父节点 
			}
			root[find(b)]=find(a);//合并两个群 
		}
	}
	for(int i=1;i<=m;i++){//如果群i的父节点是自己 
		if(root[i]==i)num++; //说明它独立 
	}cout<<num-not_all_zero;
} 

输入示例1
2 2
1 2
0
输出示例1
1
解释:用户1加入了群2,用户2未加群。如果他们想要交流的话,有两种方案:第一种是用户1再加入群1,用户2也加入群1,则两个用户总共加群2次;第二种是用户1不再加群,用户2加入群2,则两个用户总共加群1次。因此,最少加群次数为1次。

输入示例2
8 7
0
3 1 2 3
1 1
2 5 4
2 6 7
1 3
2 7 4
1 1
输出示例2
2
第二个样例:用户1加入群2,用户8加入群4。因此,总共最少还需加2次群。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

秋说

感谢打赏

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

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

打赏作者

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

抵扣说明:

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

余额充值