并查集的思路題
題意:
有 n隻襪子,k種顔色(沒啥用),需要穿m天,每天都要穿相同顔色的襪子,已知每隻襪子的顔色,求最少需要染幾隻襪子
題解:
有m天每天都穿一雙襪子,我們先把這雙襪子加到一個集合U,在把這個集合指向一個顔色點color,再計算這個集合中相同襪子的最大數量,剩餘的就是需要染色的襪子
講解集合:
這裡為什麼要用集合呢,因為題目已經滿足每天穿的襪子,是以每一個集合的顔色需要一樣,然後從每一個集合中找到需要染的色
#include<bits/stdc++.h>
using namespace std;
#define maxn 200005
int pre[maxn];
int color[maxn];
vector<int>vec[maxn];//建立一個容器
int find(int x)//查找
{
if(x!=pre[x])
{
pre[x]=find(pre[x]);
}
return pre[x];
}
void join(int x,int y)//合并為一個集合
{
int boss1=find(x);
int boss2=find(y);
if(boss1!=boss2)
{
pre[boss2]=boss1;
}
}
int main()
{
int n,m,k;
scanf("%d %d %d",&n,&m,&k);
for(int i=1;i<=n;i++)
{
pre[i]=i;
scanf("%d",&color[i]);//每隻襪子的顔色
}
int u,v;
while(m--)
{
scanf("%d %d",&u,&v);
join(u,v);//把要穿的一雙襪子加入集合
}
for(int i=1;i<=n;i++)
{
vec[find(i)].push_back(color[i]);//将和i一個集合的襪子指向color[i]
}
int ans=0;
for(int i=1;i<=n;i++)
{
map<int,int>temp;//因為數可能很大,是以需要用map處理後的數組離散化處理
//直接開數組無法離散化處理
int maxx=0;
for(int j=0;j<vec[i].size();j++)
{
temp[vec[i][j]]++;//map開的數組自動初始化,清空
maxx=max(maxx,temp[vec[i][j]]);
}
ans+=vec[i].size()-maxx;//一個集合中顔色不相同的襪子數量需要染色
}
printf("%d\n",ans);
}