题意:有n个人,每个人有k个爱好,如果两个人有某个爱好相同,他们就处于同一个集合。问总共有多少个集合,以及每个集合有多少人,并按从大到小输出。
很明显,采用并查集。vis[k]标记爱好k第一次出现的人的编号,如果为0则表示未出现。
当前第i个人若也存在爱好k,则只要将i与vis[k]两个人合并即可。
最后father[i]相同的即处在同一个集合中。
#include <iostream> #include <cstdio> #include <algorithm> #include <string.h> #include <cmath> using namespace std; /* 并查集 */ const int maxn=1005; int vis[maxn]; //vis[i]标记某爱好第一次出现在第几个人,0表示还未出现。 int n; struct UF{ int father[maxn]; void init(){ for(int i=0;i<maxn;i++){ father[i]=i; } } int find_root(int x){ if(father[x]!=x){ father[x]=find_root(father[x]); } return father[x]; } void Union(int x,int y){ int fx=find_root(x); int fy=find_root(y); if(fx!=fy){ father[fy]=fx; } } }uf; bool cmp(int a,int b){ return a>b; } int main() { char str[20]; int num,a; scanf("%d",&n); memset(vis,-1,sizeof(vis)); uf.init(); for(int i=1;i<=n;i++){ scanf("%s",str); int len=strlen(str); str[len-1]='