题目描述
silchen有N只袜子(不区分左右脚),第i只袜子的颜色是Ci,在接下去的M天,他每天都要穿2只袜子出门。我们知道接下去的第i天,他将会穿编号为ai,bi的2只袜子。
众所周知,每天穿的2只袜子颜色要是一样的。现在silchen有机会更改任意袜子的颜色,他希望可以更改最少的袜子颜色,使得每一天穿的2只袜子颜色相同。
输入
第一行输入一个T,代表数据组数,T小于等于5
每组数据第一行输入2个整数,分别表示n,m,其中n是袜子数量,m是天数,n,m均不大于100000.
第二行输入n个整数,第i个数ci表示第i只袜子颜色,保证ci不大于100000.
接下去m行每行2个整数,表示第i天穿的袜子。
输出
输出一个数字,表示最少更改的袜子数。
样例输入
1 3 2 1 2 3 1 2 2 3
复制
样例输出
2
并查集找出每个集合,因为集合中的元素互相影响所以同一 集合必须颜色相同,即把颜色改为出现最多的即可,然后每 个集合需要修改的相加
#include <bits/stdc++.h>
using namespace std;
const int mn=100010,mm=100010,mk=100010;
int n,m;
int c[mn],f[mn];
int find(int x){
int t=x;
while(x!=f[x]) x=f[x];
return f[t]=x;
}
void Union(int x,int y){
int fx=find(x),fy=find(y);
if(fx!=fy) f[fx]=fy;
}
vector<int> p[mn];
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
p[i].clear();
scanf("%d",c+i);
f[i]=i;
}
for(int i=0;i<m;i++){
int l,r;
scanf("%d%d",&l,&r);
Union(l,r);
}
for(int i=1;i<=n;++i)
p[find(i)].push_back(c[i]);
int ans=0;
for(int i=1;i<=n;++i)
if(p[i].size()>1){
map<int,int> cnt;
int mx=0;
for(int j=0;j<p[i].size();++j){
cnt[p[i][j]]++;
mx=max(cnt[p[i][j]],mx);
}
ans+=p[i].size()-mx;
}
printf("%d\n",ans);
}
return 0;
}