题目链接:SOCK
题意:看了许多遍才看懂意思,(理解力贼差)。就是说,给你n只袜子,从1-n编号,给出每只袜子的颜色,接下来m行,每行给出一个l和r,代表这天要穿的袜子编号。求为了保证每天穿的两只袜子颜色相同,至少对几只袜子染色。
思路:首先我们可以对这m对关系用并查集进行维护,把需要颜色相同的袜子放到一个集合里面去,然后使用vector存入该集合中每只袜子的颜色。然后我们要染最少的袜子,所以就应该把他们染成和(相同颜色最多的袜子的颜色)一样,就是减去该集合中颜色的众数。然后使用map维护一下颜色个数就好啦。
上代码:
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
#define maxn 200005
int col[maxn],pre[maxn]; //col 存颜色 pre并查集
vector<int>g[200005]; //这个vector存放每个集合中的袜子的颜色
int find(int x)
{
if(x!=pre[x])
pre[x]=find(pre[x]);
return pre[x];
}
void join(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx!=fy)
pre[fy]=fx;
}
int main()
{
int n,m,k,i,j,l,r;
cin>>n>>m>>k;
for(i=1;i<=n;++i)
{
pre[i]=i;
cin>>col[i];
}
for(i=1;i<=m;++i)
{
cin>>l>>r;
//并查集将同一天穿的袜子连通
join(l,r);
}
for(i=1;i<=n;++i)
{
//将在同一个集合的袜子推入同一个vector
g[find(i)].push_back(col[i]);
}
int ans=0;
for(i=1;i<=n;++i)
{
int len,maax=0;
len=g[i].size();
if(len>1)
{
//使用map找出出现次数最大的那个袜子的颜色,然后将其他袜子染成和他的颜色一样,这样次数才最少。
map<int,int>temp;
for(j=0;j<len;++j)
{
temp[g[i][j]]++;
maax=max(maax,temp[g[i][j]]);
}
ans+=len-maax;
}
}
cout<<ans;
return 0;
}