1. 程式人生 > >並查集【CF731C】Socks

並查集【CF731C】Socks

包含 const gis name str back ont 數組 col

Description

\(n\)只襪子,\(k\)種顏色,在\(m\)天中,問最少修改幾只襪子的顏色,可以使每天要穿的襪子顏色相同。

Input

第一行\(n,m,k\)分別對應題目描述。

接下來\(m\)行每行兩個整數\(l_i,r_i\)表示第\(i\)天要穿的兩只襪子的編號。

Output

一個整數,代表最小要修改幾只襪子的顏色。

首先,對於每一天要穿的襪子,我們加入同一個並查集。(這個很明顯吧)

如果有一只襪子需要被穿多次的話,

顯然我們會將其染成當前聯通塊中包含襪子最多的一種顏色。

我們用\(vector\)維護每個聯通塊中的襪子的顏色。

再開\(vis\)數組維護每種襪子的出現次數。(註意要清空

)

每次我們累加的答案就是\(size-mx\)

其中\(size\)為聯通塊大小,\(mx\)為顏色相同的最多的襪子的個數。

代碼

#include<cstdio>
#include<algorithm>
#include<vector>
#include<iostream>
#define R register

using namespace std;

const int gz=200001;

inline void in(R int &x)
{
    int f=1;x=0;char s=getchar();
    while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
    while(isdigit(s)){x=x*10+s-'0';s=getchar();}
    x*=f;
}

vector<int>v[gz];

int col[gz],f[gz],n,m,k,ans,vis[gz];

int find(R int x){return f[x]==x?x:f[x]=find(f[x]);}

signed main()
{
    in(n),in(m),in(k);
    for(R int i=1;i<=n;i++)in(col[i]),f[i]=i;
    for(R int i=1,x,y;i<=m;i++)
    {
        in(x),in(y);
        R int fa=find(x),fb=find(y);
        if(fa==fb)continue;
        f[fa]=fb;
    }
    for(R int i=1;i<=n;i++)
    {
        R int fa=find(i);
        v[fa].push_back(col[i]);
    }
    
    for(R int i=1;i<=n;i++)
    {
        R int tmp=v[i].size();
        R int mx=0;
        if(tmp>1)
        {
            for(R int j=0;j<tmp;j++)
            {
                vis[v[i][j]]++;
                mx=max(mx,vis[v[i][j]]);
            }
            for(R int j=0;j<tmp;j++)
                vis[v[i][j]]--;
            ans+=tmp-mx;
        }
    }
    printf("%d",ans); 
}

並查集【CF731C】Socks