并查集
The Suspects
有n号人,编号0~n-1,默认0号是嫌疑人,
给出m个群组,给出每个群组的成员,每个人可以在多个群组当中,一个群组中有嫌疑人则整个群组都是嫌疑人,问共多少个嫌疑人
嫌疑人/可疑者,怎么觉得像感染者
//#include <bits/stdc++.h>
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
//#define int long long
const int N=3e4+5;
int n,m;
int fa[N];
int rank[N];//按秩合并,
//本来是将元素少的集合 合并到元素多的集合,从而使得树的高度尽可能小
//这里是将编号较大的集合合并到编号较小的集合,才能使得0集合最大
int find(int x){
if(x==fa[x])return x;
return fa[x]=find(fa[x]);
}
void merge(int x,int y){
int fx=find(x);
int fy=find(y);
if(fx!=fy){
if(fx<fy){
fa[fy]=fx;
rank[fx]+=rank[fy];
}
else{
fa[fx]=fy;
rank[fy]+=rank[fx];
}
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
while(cin>>n>>m){
if(!m&&!n)break;
for(int i=0;i<n;i++)fa[i]=i,rank[i]=1;
int k,x,y;
for(int j=0;j<m;j++){
cin>>k>>x;
for(int i=1;i<k;i++){
cin>>y;
merge(x,y);
}
}
cout<<rank[0]<<endl;
}
return 0;
}
访问mp[x],即使为零,mp.size()都会增一,相当于mp.insert(x,0)
太久没做并查集,一开始没想到按秩合并,于是用map容器做,过程非常离谱
且没做对
1、本来觉得mp.insert(x,y)和mp[x]=y有什么区别,并且对于累计相同值,通过mp[x]++,非常方便,
但写了下面一段发现,mp[x]一旦访问,不管是否非零,mp.size()都会增一,相当于mp.insert(x,0),这点要注意,不能用mp.size()做结果
2、cout和printf输出结果不同????!!!!!改日再看叭
3、不知道wa在哪里,还剩思维吧
//#include <bits/stdc++.h>
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
//#define int long long
const int N=3e4+5;
int n,m;
map<int,int> mp;
//int fa[N];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
while(cin>>n>>m){
if(!m&&!n)break;
vector<vector<int> > v(m);
v.clear();
mp.clear();
int k,x;
int res=0;
for(int i=0;i<m;i++){//m个集合
cin>>k;
int f=0;
for(int j=0;j<k;j++){
cin>>x;//该组的学生编号
// fa[x]=i;//每个学生可能属于不同的集合
v[i].push_back(x);
if(x==0)f=1;
}
if(f){
for(int l=0;l<k;l++){
if(!mp[v[i][l]]){
mp[v[i][l]]=1;
res++;
}
}
}
}
if(mp.empty()){
cout<<"1"<<endl;
continue;
}
// for(int i=0;i<n;i++){
// if(!fa[i])continue;//说明学生i不考虑
// }
for(int i=0;i<m;i++){
int s=v[i].size();
int f=0;
for(int j=0;j<s;j++){
if(mp[v[i][j]]){
// res+=s;
f=1;
break;
}
}
if(f){
for(int j=0;j<s;j++){
if(!mp[v[i][j]]){
mp[v[i][j]]=1;
res++;
}
}
}
// cout<<"naiho"<<res<<endl;
// cout<<mp.size()<<endl;//mp[v[i][j]]莫非访问量,就会自动insert
}
cout<<res<<endl;
}
return 0;
}