建议复制到编译器更好食用(仅为大佬代码的个人解释)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<set>
#include<unordered_map>
using namespace std;
inline int read(){
int x=0,w=1;char ch=getchar();
while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
if(ch=='-') w = -1;
while(ch>='0' && ch<='9') x = x*10 + ch-'0', ch = getchar();
return x*w;
}
int N,M,Q;
int fa[100010]; //父系数组,用于表示各玩家之间的联系
//离散化统计父系数组fa所代表集合中每个游戏的参与人数的个数个数,
//即fa[i]中的关系网中,各游戏所参与的人数 mp[i][游戏种类]=?,该“?”表示当前关系网中的当前游戏种类所包含的人数。
map<int,int> mp[100010];
int ans[100010],cnt[100010];//ans答案保存处,cnt各种类游戏人数
int find(int x){
return (fa[x]==x ? x : fa[x]=find(fa[x]));
}
int main(){
while(~scanf("%d%d%d",&N,&M,&Q) ){
//多组案例,1.容器内容的清除或初始化
for(int i=1;i<=N;i++){
mp[i].clear();
fa[i]=i;//父系数组的重置,关系网的清除
}
memset(cnt,0,sizeof(cnt));
memset(ans,-1,sizeof(ans));//数组初识化。
//每个人想玩游戏,信息填入,统计
int x;
for(int i=1;i<=N;i++){
scanf("%d",&x);
mp[i][x]++;// i 集群的 x 游戏人数加一
cnt[x]++;
}
//网线的接入,关系网的形成,集群中各游戏人数的更新。(mp是与fa相关联的)
int u,v;
for(int i=1;i<=Q;i++){
scanf("%d%d",&u,&v);
u=find(u),v=find(v);//找到属于自己的集群
//小集群融入大集群
if(mp[u].size()<mp[v].size()) swap(u,v);//以游戏种类划分?
fa[v]=u;//小集群的父系 指向 大集群
//更新大集群的数据,即把小集群添加到大集群中
for(auto j:mp[v] ){
mp[u][j.first]+=j.second;//当前游戏种类j.first的人数相加,mp[x][j.first]+mp[v][j.first]
//ans答案的统计
if(mp[u][j.first]==cnt[j.first]&&ans[j.first]==-1)
ans[j.first]=i;//当前添加网线的编号
}
mp[v].clear();//清除小集群
}
for(int i=1;i<=M;i++){
if(cnt[i]==1) printf("0\n");
else if (cnt[i]==0) printf("-1\n");
else printf("%d\n",ans[i]);
}
}
return 0;
}