题目链接
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;
}