并查集找出互为一组的袜子,它们的颜色要是一样的。
然后要把x组袜子高效的分离,使用sort重写cmp就可以很简单的给他们排序(或者用指针数组记录偏移量),相邻的为一组。
再然后通过排序后的标号找到颜色,通过all记录颜色出现的次数,通过队列把前一组的颜色置0即可。
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <stack>
#include <string>
#include <iostream>
#include <deque>
using namespace std;
int fa[200010];
int color[200010];
int inf[200010];
int all[200010];
int getfa(int now)
{
if(fa[now]==now) return now;
return fa[now]=getfa(fa[now]);
}
void add(int a,int b)
{
a=getfa(a);
b=getfa(b);
if(a!=b) fa[a]=b;
}
bool cmp(int &a,int &b)
{
return getfa(a)<getfa(b);
}
int main()
{
int i,j,k,l,t,n,m;
scanf("%d",&n);scanf("%d",&m);scanf("%d",&k);
for(i=1;i<=n;i++) scanf("%d",&color[i]);
for(i=1;i<=n;i++) fa[i]=i;
for(i=1;i<=m;i++)
{
scanf("%d",&j);scanf("%d",&l);
add(j,l);
}
for(i=1;i<=n;i++) inf[i]=i;
sort(inf+1,inf+1+n,cmp);
memset(all,0,sizeof all);
all[color[inf[1]]]++;
queue<int >q;
q.push(color[inf[1]]);
int maxx=1;
int cnt=1;
int ans=0;
for(i=2;i<=n;i++)
{
if(getfa(inf[i])!=getfa(inf[i-1]))
{
ans+=cnt-maxx;
cnt=0;
maxx=0;
while(!q.empty())
{
all[q.front()]=0;
q.pop();
}
}
all[color[inf[i]]]++;
cnt++;
if(all[color[inf[i]]]>maxx)
maxx=all[color[inf[i]]];
q.push(color[inf[i]]);
}
ans+=cnt-maxx;
cnt=0;
maxx=0;
printf("%d",ans);
return 0;
}