http://codeforces.com/problemset/problem/731/C
并查集+贪心 将要求颜色相同的袜子序号放入一个集合中
贪心:然后统计这个集合中出现次数最多但颜色 可以得到这个集合要repain的次数
代码有难度
统计集合数
int tot;//总的集合数
for (int i = 1; i <= n; i++)
if(par[i] == i)
{
rec[tot++] = i;//记录根节点
}
//统计每个集合红颜色的个数
map<int, int> clmp;
vector<int> G[MAXN];
for(int i = 1; i <= n; i++)
{
G[par[i]].push_back(color[i]);
}
int ans = 0;
for(int i = 0; i < tot; i++)//统计颜色情况
{
clmp.clear();
for (int j = 0; j < v[rec[i]].size(); j++)
clmp[v[rec[i]][j]]++;
}
1 #include <bits/stdc++.h> 2 #define MAXN 200007 3 using namespace std; 4 5 int par[MAXN]; 6 7 int find(int x) 8 { 9 if (par[x] == x) return x; 10 else return par[x] = find(par[x]); 11 } 12 bool same(int x, int y) 13 { 14 int px, py; 15 px = find(x); 16 py = find(y); 17 return px == py; 18 } 19 void unite(int x, int y) 20 { 21 int px = find(x); 22 int py = find(y); 23 par[px] = py; 24 } 25 int color[MAXN]; 26 int rec[MAXN]; 27 vector<int> v[MAXN]; 28 map<int,int> clmap; 29 int main() 30 { 31 int day, paint, socks, ans = 0; 32 scanf("%d%d%d", &socks, &day, &paint); 33 for (int i = 0; i <= socks; i++) par[i] = i; 34 for (int i = 1; i <= socks; i++) 35 { 36 scanf("%d", &color[i]); 37 } 38 for (int i = 0; i < day; i++) 39 { 40 int l, r; 41 scanf("%d%d", &l, &r); 42 unite(l, r); 43 } 44 int tot = 0; 45 for (int i = 1; i <= socks; i++) 46 { 47 if (i == find(i)) 48 { 49 rec[tot++] = i; 50 } 51 } 52 for (int i = 1; i <= socks; i++) 53 { 54 v[par[i]].push_back(color[i]); 55 } 56 for (int i = 0; i < tot; i++) 57 { 58 clmap.clear(); 59 for(int j = 0; j < v[rec[i]].size(); j++) 60 { 61 clmap[v[rec[i]][j]]++; 62 } 63 map<int,int> :: iterator it; 64 int maxn = 0; 65 for (it = clmap.begin(); it != clmap.end(); it++) 66 { 67 maxn = max(maxn, (*it).second); 68 } 69 ans += v[rec[i]].size() - maxn; 70 } 71 cout << ans << endl; 72 }