CF731C Socks 并查集的简单使用
简要题意
给出n个袜子,一共k种颜色,有m天,每天选两个不相同的袜子穿。
你需要一开始改变其中的袜子的颜色,使得之后m天的穿着计划里,每天的两只袜子颜色相同,最少改几只袜子的颜色。
对于第x只袜子,如果它和y在同一天穿,那么可以把它们两个连起来。
最后可以形成几块联通图,对于每一个联通子图来说,子图里的每一个节点都会相互影响。
所以可以贪心的想,把子图的所有节点都变成颜色最多的那一个。然后累计答案。
相连的节点具用传递性,如果不把联通子图的颜色统一,则必定至少有一天的颜色不同,以下为代码
void solve()
{
n = q_;
m = q_;
k = q_;
ffp(i, 1, n) { fa[i] = i; }
ffp(i, 1, n)
{
num[i] = q_;
}
ffp(i, 1, m)
{
unio(q_, q_);
}
map<int,map<int,int>>ma;
ffp(i, 1, n)
{
find(i);
ma[fa[i]][num[i]]++;//父节点是偏向编号小的那一边
}
int ans = 0;
for (auto e : ma)
{//父节点为u的联通子图
auto [u, temp] = e;
int maxx = -iINF;//这个子图元素最多的数量
int sum = 0;//这个子图总数量
for (auto p : temp)
{
maxx = max(maxx, p.second);
sum += p.second;
}
ans += sum - maxx;
}
cout << ans << endl;
}