CF731C Socks

文章通过一个关于袜子配对的问题,介绍了如何运用图论中的连通块概念,以及如何用深度优先搜索(DFS)和并查集来解决此类问题。在解决过程中,作者强调了识别问题的图论模型、优化遍历策略以及理解并查集的应用的重要性。
摘要由CSDN通过智能技术生成

知识点:连通块

这个题首先要看出是图论的模型,因为a和b在一起,b和c在一起,那么想让所有的天数脚上的袜子都一样,那么这三个袜子的颜色都要是一样的,那么就很简单了,袜子就是结点,两脚穿的袜子就是一条无向边,这种连通性的问题用深搜和并查集都可以的,选择使用了深搜,最后的答案就是每个连通块累加,每个连通块的答案就是这个连通块的大小,减去,这个连通块里面出现次数最多的颜色的出现次数,这样这个题就解决了

一开始因为代码问题没有使用并查集,后面去学习了一下并查集的写法,主要是每个连通块统计完答案之后现场还原的问题,后面看了别人代码发现遍历两次就行了,也不是死脑筋非要遍历一次就行的,也不是遇到这种情况都用memset,这样会浪费很多时间

还有,这个题是因为是并查集的练习题才看出了里面的图论模型,这个如果没有这个提示,很有可能看不出来

#include <bits/stdc++.h>

using namespace std;

const int N = 2e5 + 5;

int tot, ver[N * 2], nxt[N * 2], head[N];
int a[N], vis[N], cnt;
map<int, int> mp;

void add(int x, int y) {
	ver[++tot] = y;
	nxt[tot] = head[x]; head[x] = tot;
}

void dfs(int x) {
	vis[x] = 1;
	cnt++;
	mp[a[x]]++;
	for (int i = head[x]; i; i = nxt[i]) {
		int y = ver[i];
		if (!vis[y]) dfs(y);
	}
}

int main() {
	int n, m, k;
	cin >> n >> m >> k;
	for (int i = 1; i <= n; i++) {
		scanf("%d", a + i);
	}
	while (m--) {
		int x, y;
		scanf("%d%d", &x, &y);
		add(x, y); add(y, x);
	}
	int ans = 0;
	for (int i = 1; i <= n; i++) {
		if (!vis[i]) {
			mp.clear();
			cnt = 0;
			dfs(i);
			int Max = 0;
			for (auto it = mp.begin(); it != mp.end(); it++) {
				if (it->second > Max) Max = it->second;
			}
			ans += cnt - Max;
		}
	}
	cout << ans;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值