并查集的应用
用map保存每个人所听到的声音,如果两个人听到的树完全相等,归到同一个类中
注意没有听到任何声音的人也算是一种opnion
#include <cstdio>
#include <iostream>
#include <cstring>
#include <map>
using namespace std;
#define MAX 101
int n,m,id[MAX],size[MAX],cnt;
map<int,map<int,int> >g;
int find(int p){
return p==id[p]?p:id[p]=find(id[p]);
}
void uni(int p,int q){
int pp=find(p),pq=find(q);
if(pp==pq)return ;
if(size[pp]>size[pq]){
id[pq]=pp;
size[pp]+=size[pq];
}else{
id[pp]=pq;
size[pq]+=size[pp];
}
cnt--;
}
void init(){
g.clear();
for(int i=0;i<=n;++i){
id[i]=i;
size[i]=1;
}
}
char buf[20];
int main(){
int t;a
scanf("%d",&t);
while(t--){
scanf("%d%d\n",&n,&m);
init();
while(gets(buf)&&strcmp(buf,"")){
int u,v;
sscanf(buf,"%d%d",&u,&v);
g[u][v]=1;
}
cnt=g.size();
if(n>g.size())cnt++;
map<int,map<int,int> >::iterator it1=g.begin();
for(;it1!=g.end();++it1){
map<int,map<int,int> >::iterator it2=g.begin();
for(;it2!=g.end();++it2){
if(it1->second==it2->second)
uni(it1->first,it2->first);
}
}
printf("%d\n",cnt);
if(t)printf("\n");
}
return 0;
}