• Codeforces 731C:Socks(并查集)


    http://codeforces.com/problemset/problem/731/C

    题意:有n只袜子,m天,k个颜色,每个袜子有一个颜色,再给出m天,每天有两只袜子,每只袜子可能不同颜色,问要让每天的袜子是相同颜色的,要重新染色的袜子数最少是多少。

    思路:并查集合并,将同一天的袜子合并起来,然后就形成了cnt个集合,每个集合都是独立的,因此排序,找出每个集合里面袜子颜色相同的最多的是哪个颜色,然后把其他不属于这个颜色的都染成这个颜色,那么这样重新染色的袜子数是最少的。然后每个集合的答案加起来就是最后的结果了。还怕这样太暴力会超时,还好没有。

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <string>
     6 #include <cmath>
     7 #include <queue>
     8 #include <vector>
     9 #include <map>
    10 #include <set>
    11 using namespace std;
    12 #define INF 0x3f3f3f3f
    13 #define N 200010
    14 typedef long long LL;
    15 int fa[N], col[N], root[N], vis[N];
    16 vector<int> vec[N];
    17 
    18 int Find(int x) {
    19     if(x == fa[x]) return x;
    20     return fa[x] = Find(fa[x]);
    21 }
    22 
    23 void Merge(int x, int y) {
    24     x = Find(x), y = Find(y);
    25     if(x == y) return ;
    26     fa[x] = y;
    27 }
    28 
    29 int main() {
    30     int n, m, k;
    31     cin >> n >> m >> k;
    32     for(int i = 1; i <= n; i++) {
    33         fa[i] = i;
    34         scanf("%d", &col[i]);
    35     }
    36     for(int i = 0; i < m; i++) {
    37         int u, v;
    38         scanf("%d%d", &u, &v);
    39         vis[u] = vis[v] = 1;
    40         Merge(u, v);
    41     }
    42     int cnt = 0;
    43     for(int i = 1; i <= n; i++) {
    44         if(vis[i]) {
    45             if(fa[i] == i) root[++cnt] = i;
    46             vec[Find(i)].push_back(col[i]);
    47         }
    48     }
    49     int ans = 0;
    50     for(int i = 1; i <= cnt; i++)
    51         sort(vec[root[i]].begin(), vec[root[i]].end());
    52     for(int i = 1; i <= cnt; i++) {
    53         int now = 1, ma = 0;
    54         for(int j = 1; j < vec[root[i]].size(); j++) {
    55             if(vec[root[i]][j] != vec[root[i]][j-1]) {
    56                 ma = max(ma, now); now = 1;
    57             } else now++;
    58         }
    59         ma = max(now, ma);
    60         ans += vec[root[i]].size() - ma;
    61     }
    62     printf("%d
    ", ans);
    63     return 0;
    64 }
  • 相关阅读:
    文件比较运算符
    中山慧海人才市场9月份 现场招聘会预告
    80后智能科技公司诚聘业务人员
    元豪路灯厂诚聘
    对Discuz的简单认识
    discuz阅读权限的设置作用
    个人对织梦系统的认识
    awvs的用法
    cain使用方法
    CCNA笔记(1)
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6246940.html
Copyright © 2020-2023  润新知