Codeforces731C-Socks(并查集)

来源:互联网 发布:文件夹整理软件 编辑:程序博客网 时间:2024/04/28 07:13

题目链接

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

思路

只要两只袜子同时穿,那么就放进一个集合里面,最后统计一下每个集合里面出现颜色最多的,这样这个颜色就可以不改变,这个集合里面的其他袜子全部变成这个颜色

细节

统计每个集合里面的出现最多的颜色的时候,如果直接用数组来统计会爆内存,于是用的数组+map

代码

#include <iostream>#include <cstring>#include <stack>#include <vector>#include <set>#include <map>#include <cmath>#include <queue>#include <sstream>#include <iomanip>#include <fstream>#include <cstdio>#include <cstdlib>#include <climits>#include <deque>#include <bitset>#include <algorithm>using namespace std;#define PI acos(-1.0)#define LL long long#define PII pair<int, int>#define PLL pair<LL, LL>#define mp make_pair#define IN freopen("in.txt", "r", stdin)#define OUT freopen("out.txt", "wb", stdout)#define scan(x) scanf("%d", &x)#define scan2(x, y) scanf("%d%d", &x, &y)#define scan3(x, y, z) scanf("%d%d%d", &x, &y, &z)#define sqr(x) (x) * (x)const int maxn = 200000 + 5;int a[maxn], p[maxn], c[maxn], r[maxn], vis[maxn];int n, m, k;int find(int x) {    return p[x] == x ? x : p[x] = find(p[x]);    }void Union(int x, int y) {    x = find(x); y = find(y);    if (x != y) {        if (r[x] > r[y]) {            p[y] = x;            r[x] += r[y];        } else {            p[x] = y;            r[y] += r[x];        }    }}map<int, int> ma[maxn];int main() {    scan3(n, m, k);    for (int i = 1; i <= n; i++) scan(c[i]);    for (int i = 1; i <= n; i++) p[i] = i;    for (int i = 1; i <= n; i++) r[i] = 1;    for (int i = 1; i <= m; i++) {        int x, y;        scan2(x, y);        Union(x, y);    }    int res = 0;    for (int i = 1; i <= n; i++) {        ma[find(i)][c[i]]++;    }    for (int i = 1; i <= n; i++) {        if (r[find(i)] == 1 || vis[find(i)]) continue;        int tnum = 0;        vis[find(i)] = 1;        for (map<int, int>::iterator it = ma[find(i)].begin(); it != ma[find(i)].end(); it++)             tnum = max(tnum, it->second);        res += (r[find(i)] - tnum);    }    printf("%d\n", res);    return 0;}
0 0