CodeForces Two Sets(并查集)
来源:互联网 发布:刘慈欣光荣与梦想知乎 编辑:程序博客网 时间:2024/05/19 21:45
题目链接:http://codeforces.com/problemset/problem/468/B
题目大意:给你N个互不相同的整数,再给两个整数a,b,问能否把这N个数分成两部分,使得在a这个集合中的任一个数ai,都存在a-ai也在a 这个集合中,对b集合也同理。如果不存在一种合理分法,输出No,否则输出YES,并输出任一种合理分组。
解题思路:
首先我们先假设存在一种合理的方案,则有 对于任一个数x,肯定在a,b集合中的一个。同时如果方案合理,最后的结果a,b集合中的元素没有交集。
1.对于一个数x,如果a-x不存在,则x肯定在b分组中(假定分组成立),则把x和b分组并起来;如果同时b-x也不存在的话,则再把x和a分组并起来,此时a和b分组被并了起来,显然这种方案不合理。
2.对于一个数x,如果a-x存在,则把x和a-x对应的下标并起来,此时并不能说明x属于集合a,因为可能存在N=2,a=8,b=20,4,16,这样的数据,只有当b-x不存在时,才把x和a的下标并起来。
3,如果b-x也存在时,就把x和b-x也的下标也并起来,此时如果x!=a-x!=b-x时,说明a和b集合公用x,即这种方案a和b被并起来,这种方案也不合理。此时如果x==a-x!=b-x,显然应分组为b,当然特例就是a和b相等,此时任何分组都可以。
总的情况应该这几种。
对于代码,有以下几点感觉很好:
1,map映射,使得查找成对的数字查找更方便。
2,虚拟出两个a,b集合的根结点n+1和n+2;
3,并查集的特殊处理;
关于这道题我自己写的是满足a集合就放在a集合中, 满足b集合在放在b集合中;然后用各种标记和判断来判是否合法, 但是就写不过去, 然而看了别人的题解后发现,如果反着考虑会省很多麻烦, 所以写博客来提醒一下。
#include<stdio.h>#include<string.h>#include<algorithm>#include<map>using namespace std;const int maxn = 1e5 + 100;int f[maxn], s[maxn];int find_set(int x){ return x==f[x]? x : f[x]=find_set(f[x]);}void merge_set(int x, int y){ int fx = find_set(x); int fy = find_set(y); if(fx != fy) f[fx] = fy;}int main(){ int n, a, b, x; scanf("%d%d%d", &n, &a, &b); map<int, int> M; for(int i = 1; i <= n+2; i++) f[i] = i; for(int i = 1; i <= n; i++) { scanf("%d", &s[i]); M[s[i]] = i; } for(int i = 1; i <= n; i++) { x = a - s[i]; if(M[x] != 0) merge_set(i, M[x]); else merge_set(i, n+2); x = b - s[i]; if(M[x] != 0) merge_set(i, M[x]); else merge_set(i, n+1); } int fx = find_set(n+1); int fy = find_set(n+2); if(fx == fy) puts("NO"); else { puts("YES"); for(int i = 1; i <= n; i++) { int x = find_set(i); if(i == 1) { if(x == fx) printf("0"); else printf("1"); } else { if(x == fx) printf(" 0"); else printf(" 1"); } } } return 0;}
- CodeForces Two Sets(并查集)
- codeforces 468B Two Sets 并查集
- codeforces 468B Two Sets 并查集变形
- Codeforces 468B Two Sets 并查集
- CODEFORCES 468B Two Sets ---并查集建树
- Codeforces 469D Two Sets【思维+并查集】
- Codeforces Round #268 (Div. 2) D Two Sets[并查集]
- (one day one problem) codeforces 468/problem/B Two Sets (并查集)
- 并查集 (Union-Find Sets)
- 并查集 (Union-Find Sets)
- 并查集 (Union-Find Sets)
- 并查集Union-Find Sets
- 并查集-(union-find sets)
- 并查集 (Union-Find Sets)
- 并查集 (Union-Find Sets)
- Disjoint sets(并查集)
- 并查集Union-Find Sets
- 并查集(Union-find Sets)
- window 查看端口占用进程 并杀死
- iOS中获取系统时间
- 移动聚合广告哪家强,芒果?Keymob?Adview?
- 你会做Web上的用户登录功能吗?
- Android应用开发性能优化完全分析
- CodeForces Two Sets(并查集)
- 设置eclipse的debug提醒
- tomcatec出错-Web app root system property already set to different value
- 晶格振动
- [LeetCode-82] Remove Duplicates from Sorted List II
- 高并发memecache 学习视频
- Java 读取properties配置文件
- 【OCJP】 第3题---类变量的初始化
- Google Guava Collections 使用介绍