ACM-ICPC寒假算法训练2:高级数据结构1(并查集):基础并查集
2021/6/8 20:22:20
本文主要是介绍ACM-ICPC寒假算法训练2:高级数据结构1(并查集):基础并查集,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
并查集训练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; }
这篇关于ACM-ICPC寒假算法训练2:高级数据结构1(并查集):基础并查集的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享