• CodeForces 731C


    题意

    Arseniy的所有袜子按照1-n编号, 每个袜子的颜色标记为c[i], 现在给出n个袜子和m天的穿袜子方案, 至多有k种颜色( 感觉是无用条件 ), 现在要求她每天穿着方案的两只袜子同色, Arseniy可以将其涂色改变颜色, 求最少的涂色数量

    思路

    比较容易想到并查集
    将每天穿着方案中的两只袜子合并到同一个根节点下, 同一个集合中的袜子必须涂成同一种颜色, 这里用非常简单的贪心思想, 肯定是要将出现颜色次数最多的颜色保留, 剩下的涂色涂成这个颜色
    之前T在test47上, 才发现并查集的_find()函数写的有点问题, 应该利用 _find()函数更新父节点
    正确的_find() 函数 :

    int _find(int a){
        if( f[a] != a )
            f[a] = _find(f[a]);
        return f[a];
    }

    AC代码

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <map>
    using namespace std;
    
    const int maxn = 200000+5;
    int c[maxn], f[maxn];
    map<int, int> mp[maxn];
    int n;
    
    int _find(int a){
        if( f[a] != a )
            f[a] = _find(f[a]);
        return f[a];
    }
    
    void _union(int a, int b){
        int aa = _find(a), bb = _find(b);
        if( aa != bb ) f[bb] = aa;
        return;
    }
    
    int main()
    {
        int m, k;
        int a, b, mmax, all, ans;
        scanf("%d%d%d",&n, &m, &k);
        for( int i = 1; i <= n; i++ ){
            scanf("%d",&c[i]);
            f[i] = i;
        }
        while(m--){
            scanf("%d%d", &a, &b);
            _union(a, b);
        }
        for( int i = 1; i <= n; i++ )
            mp[_find(i)][c[i]]++;
        ans = 0;
        map<int, int>::iterator it;
        for( int i = 1; i <= n; i++ ){
            it = mp[i].begin();
            mmax = 0;
            all = 0;
            for( ; it != mp[i].end(); it++ ){
                all += it->second;
                mmax = max(mmax, it->second);
            }
            ans += (all-mmax);
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    博客园——程序员
    PHP获取IP
    VIM使用笔记
    再见,帕金!
    A Song of My Heart
    读书...
    纪念日...
    一路向北
    韬光养晦,希望能有所作为
    一首好歌!
  • 原文地址:https://www.cnblogs.com/JinxiSui/p/9740545.html
Copyright © 2020-2023  润新知