POJ 1703 Find them, Catch them(并查集)
2016-06-04 11:12
531 查看
分析:并查集的拓展题目。一般的思路是先初始化,各个数自成一个组,然后是两个gangs自成一个组,但由于两个给定元素有三种关系: In the same gang; In different gangs; Not sure yet; 采用此模型的缺点是判断两个元素关系还未确定这种情况比较复杂,故模型需要改进。本题的正确模型是将已经确定关系的元素组成一个集合,然后利用两个元素的根节点是否是同一个来确定这两个元素之间的关系。pre[a]中存放的是a的根结点,relation中存放的是pre[a]与a的关系,0表示两者不在同一个gangs中,1表示两者在同一个gangs中。具体的程序还是沿袭了并查集的init_set()、find()、union()的三步骤。
代码如下:
注意:如果将代码中的scanf和printf改为cin和cout会超时。
参考:poj-1703 Find them, Catch them
代码如下:
#include<iostream> #include<cstdio> using namespace std; const int N = 100004; int t, m, n; int pre ; int relation ; void init_set() { for (int i = 1; i <= n; ++i) { pre[i] = i; relation[i] = 1; } } int find(int a) { if (a == pre[a]) { return a; } int temp = find(pre[a]); if (!relation[pre[a]]) { relation[a] = !relation[a]; } pre[a] = temp; return temp; } void union_crime(int one, int two) { int root1 = find(one); int root2 = find(two); if (root1 != root2) { tr[root2] = root1; relation[root2] = (relation[one] + relation[two]) % 2; } } int main() { char op; int one, two; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); init_set(); for (int i = 0; i < m; ++i) { getchar(); scanf("%c%d%d", &op,&one, &two); if (op == 'D') { union_crime(one, two); } else { if (find(one) != find(two)) { printf("Not sure yet.\n"); } else if (relation[one] == relation[two]) { printf("In the same gang.\n"); } else { printf("In different gangs.\n"); } } } } return 0; }
注意:如果将代码中的scanf和printf改为cin和cout会超时。
参考:poj-1703 Find them, Catch them
相关文章推荐
- JSP(JavaServer Pages)不是Java Script(JS)
- 2016/6/3 1002. 可排序数组
- 购书优惠问题
- tensrflow python [defunct]
- 一个例子看懂异步代码执行效率
- LeetCode Palindrome Linked List
- 输入框中将小写转化为大写。
- 关于在小米手机上配置Sqlite3的问题
- C++ inline 函数
- cron 表达式
- Oracle绿色客户端(Instant Client)配置方法
- NYOJ 1121 最小周期串
- HTML知识点链接
- 开发过程中常用的Linux命令
- DES加密中文乱码问题的解决
- Cocos2dx-Lua与C++混合使用
- 时间操控工具类
- W-01. 映射 Web 服务器 ❀ 沃奇卫士 (WatchGuard) 防火墙
- SQL Server存储内幕系列
- SVG格式的图片来优化网站