ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

ACM-ICPC寒假算法训练2:高级数据结构1(并查集):基础并查集

2021-06-08 20:04:47  阅读:198  来源: 互联网

标签:py return int px 查集 ACM ICPC ++ find


并查集训练1:基础并查集

题1:也可在HDOJ 1213提交

算法分析:

这题就是数朋友圈的数目,可以用并查集或者DFS,说明并查集可以用于计算联通块的数目。只需要把是朋友的并在一起,选取一个作为代表,然后去数有多少个代表就是有多少个圈子。

Solving code:

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>

const int maxn = 1005;
int t, n, m, p[maxn];

int find(int x) {
	if (x == p[x])
		return x;
	return p[x] = find(p[x]);
}

void merge(int x, int y) {
	int px = find(x), py = find(y);
	if (px != py)
		p[py] = px;
}

int main() {
	scanf("%d", &t);
	while (t--) {
		scanf("%d %d", & n, &m);
		for (int i = 1; i <= n; i++)
			p[i] = i;
		int ans = 0;
		for (int i = 0; i < m; i++) {
			int a, b;
			scanf("%d %d", &a, &b);
			merge(a, b);
		}
		for (int i = 1; i <= n; i++) {
			if (i == p[i])
				ans++;
		}
		printf("%d\n", ans);
	}
	return 0;
}

题二:POJ 2524 有多少种宗教被人信仰

算法分析:

这题的算法和上一题是一样的,完全一样,就是同一信仰的人被合并到一起,去数有多少种信仰就可以了!

Solving code:

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>

const int maxn = 5e4 + 5;
int kcase, n, m, p[maxn];

int find(int x) {
	if (x == p[x])
		return x;
	return p[x] = find(p[x]);
}

void merge(int x, int y) {
	int px = find(x), py = find(y);
	if (px != py)
		p[py] = px;
}

int main() {
	while (scanf("%d %d", &n, &m) && (n || m)) {
		kcase++;
		for (int i = 1; i <= n; i++)
			p[i] = i;
		int ans = 0;
		for (int i = 0; i < m; i++) {
			int a, b;
			scanf("%d %d", &a, &b);
			merge(a, b);
		}
		for (int i = 1; i <= n; i++)
			if (i == p[i])
				ans++;
		printf("Case %d: %d\n", kcase, ans);
	}
	return 0;
}

题三:POJ 1611 有多少嫌疑人

算法分析:

这题比前两天稍微有意思一点,但是也是简单题。我们设定编号为 0 的是嫌疑人,和 0 一组的都是嫌疑人,问有多少个嫌疑人。那样我们可以每组并在一起,以为我们并不一定是以0 为 0所在组的代表,所以我们做最后统计的时候,万万不可以:if(!p[i]) ans++;这样是绝对错误的!因为我们的 0 可能最后的p[0] != 0,所以我们应该要去搜索 i 所在的组,是不是与 0 同组:if(find(i) == p[0]) ans++;

Solving code:

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>

const int maxn = 5e4 + 5;
int n, m, p[maxn];

int find(int x) {
	if (x == p[x])
		return x;
	return p[x] = find(p[x]);
}

void merge(int x, int y) {
	int px = find(x), py = find(y);
	if (px != py)
		p[py] = px;
}

int main() {
	while (scanf("%d %d", &n, &m) && (n || m)) {
		for (int i = 0; i < n; i++)
			p[i] = i;
		int ans = 0;
		for (int i = 0; i < m; i++) {
			int k, a, b;
			scanf("%d", &k);
			if (k--)	scanf("%d", &a);
			while (k--) {
				scanf("%d", &b);
				merge(a, b);
			}
		}
		for (int i = 0; i < n; i++)
			if (find(i) == p[0])
				ans++;
		printf("%d\n", ans);
	}
	return 0;
}

标签:py,return,int,px,查集,ACM,ICPC,++,find
来源: https://blog.51cto.com/u_15262702/2883326

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有