给你n,m,k
n袜子的种类
m天数
k你可以改的颜色范围
再给你n种袜子的颜色
再告诉你m天,我每天穿了哪种袜子(两只)
你必须用最少的次数去修改某些袜子的颜色,使得每天,两种袜子的颜色一样。
input
3 2 3
1 2 3
1 2
2 3
output
2
input
3 2 2
1 1 2
1 2
2 1
output
0
并查集把必须相等的种类合并起来,形成多个集合。
在每一个集合内,我肯定改成颜色最多的那种袜子(在集合内最多)
用边表把集合内的元素与根连起来,暴力累加。
#include
#include
#include
#include
#define ll long long
using namespace std;
int n,m,k,x,y,u,v,tot,ans,Max;
int f[200005],c[200005],s[200005],have[200005];
int head[200005],Next[200005],to[200005];
int get(int x)
{
if(f[x]==x) return x;else return f[x]=get(f[x]);
}
void add(int x,int y)
{
tot++;
Next[tot]=head[x];
to[tot]=y;
head[x]=tot;
}
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=n;i++) scanf("%d",&c[i]);
for(int i=1;i<=n;i++) f[i]=i,s[i]=1,head[i]=-1;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
u=get(x);
v=get(y);
if(v!=u)
{
f[v]=u;
s[u]=s[u]+s[v];
s[v]=0;
}
}
for(int i=1;i<=n;i++)
{
f[i]=get(i);
add(f[i],i);
}
for(int i=1;i<=n;i++)
if(f[i]==i)
{
Max=0;
for(int j=head[i];j!=-1;j=Next[j])
{
have[c[to[j]]]++;
Max=max(Max,have[c[to[j]]]);
}
ans=ans+s[i]-Max;
for(int j=head[i];j!=-1;j=Next[j]) have[c[to[j]]]--;
}
cout<return 0;
}