您的位置:首页 > 其它

CodeForces 731C C - Socks 并查集

2017-08-07 17:07 239 查看
题目链接:点击打开链接

题目大意:n只袜子,并对袜子标号为1-n。然后用k种颜色对n只袜子染色.

接下来给出m天要用的袜子(每天2只),要求这使这m天,每天两只袜子的颜色相同,问至少需要染几只袜子。

思路就是:

首先用并查集,将他们分组,同一天的袜子最后要求颜色相同,所以将他们分入同一个并查集。

然后用vector数组存储每个并查集,要求同一个并查集中的袜子要是相同的颜色。那么本来有2号颜色是最多的话。那么其它都要变成2号颜色。

即通过一个数组对并查集内的每种颜色的袜子进行统计,那么对于每个并查集需要变化的袜子数等于并查集总的袜子数量减去某个颜色最多的袜子数量,即除了袜子数量最多的颜色,其他颜色的袜子都需要变成这个颜色。

这里我们注意下都对这个统计颜色数量的数组清零的操作,不能用memset,会超时,改变了哪个颜色,最后就把他清0即可。

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn=200100;
int pre[maxn];
int n,m,k;
int color[maxn];
vector<int>v[maxn];
int num[maxn];
int init()
{
for(int i=1;i<=n;i++)
{
scanf("%d",&color[i]);
pre[i]=i;
}
memset(num,0,sizeof num);
}
int fid(int x)
{
int r=x;
while(pre[r]!=r)
r=pre[r];
int i=x,j;
while(i!=r)
{
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
void join(int x,int y)
{
int fx=fid(x),fy=fid(y);
if(fx!=fy)
{
pre[fx]=fy;
}
}
int main(void)
{
int a,b;
while(~scanf("%d%d%d",&n,&m,&k))
{
init();
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
join(a,b);
}
for(int i=1;i<=n;i++)
{
v[fid(i)].push_back(i);//将每个元素加入到相应的并查集中去
}
int ans=0;
for(int i=1;i<=n;i++)
{
if(v[i].size()==0)continue;
//memset(num,0,sizeof num);
int maxe=-1;
for(int j=0;j<v[i].size();j++)
{
num[color[v[i][j]]]++;
}

for(int j=0;j<v[i].size();j++)
{
maxe=max(maxe,num[color[v[i][j]]]);
num[color[v[i][j]]]=0;
}

// cout<<v[i].size()<<endl;
ans+=v[i].size()-maxe;

}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: