POJ 1703 Find them, Catch them
http://poj.org/problem?id=1703
应该是书上例题(食物链 POJ1822)的简单版
这里同样用书上很巧妙的思路
如何表达 在集合A 和 集合B 中
并不是 让i.set = A 类似于这样活着P[i] = A
而是将 这个变成一个隐形条件 并且 不用再关心 i到底是在A集合 还是在B集合
建立并查集par[2*N]
让i 表示在集合A 中 i +N 表示在集合B 中
当两个数在同一集合(有共同根节点)时 说明这样的时间必然发生
及如果same(i, j+N) 则说明 i 在集合A中 j在集合B中 --->>>>i j 一定不再同一个集合中
这样简化问题 不再纠结于 i到底是在A 还是在B 而是针对问题 操作
注意不要用cin 会超时
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #define N 100007 5 using namespace std; 6 7 int par[2*N]; 8 int rank[2*N]; 9 int find(int x) 10 { 11 if (x == par[x]) return x; 12 else return par[x] = find(par[x]); 13 } 14 15 void unite(int x, int y) 16 { 17 int px = find(x), py = find(y); 18 if (px == py) return ; 19 else if (rank[px] > rank[py]) 20 { 21 par[py] = px; 22 } 23 else 24 { 25 par[px] = py; 26 if (rank[px] == rank[py]) rank[py]++; 27 } 28 } 29 30 bool same(int x, int y) 31 { 32 int px = find(x), py = find(y); 33 return px == py; 34 } 35 int main() 36 { 37 int T, n, M; 38 freopen("in.txt", "r", stdin); 39 scanf("%d", &T); 40 while(T--) 41 { 42 scanf("%d%d", &n, &M); 43 for (int i = 1;i <= 2*n; i++) 44 { 45 par[i] = i; 46 rank[i] = 1; 47 } 48 char ch; 49 int a, b; 50 for (int i = 0; i < M; i++) 51 { 52 //cin >> ch;//用cin 读取 char 可以避免换行符 但是会超时 因为 输入规模比较大 53 getchar(); 54 scanf("%c", &ch); 55 scanf("%d%d", &a, &b); 56 if (ch == 'A') 57 { 58 if ( same(a, b) || same(a, b+n) ) 59 { 60 if ( same(a, b) ) printf("In the same gang.\n"); 61 else printf("In different gangs.\n"); 62 } 63 else printf("Not sure yet.\n"); 64 } 65 else 66 { 67 unite(a, b+n); 68 unite(a+n, b); 69 } 70 } 71 } 72 return 0; 73 }
标签:
并查集
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
【推荐】AI 的力量,开发者的翅膀:欢迎使用 AI 原生开发工具 TRAE
【推荐】2025 HarmonyOS 鸿蒙创新赛正式启动,百万大奖等你挑战
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
· AES 加密模式演进:从 ECB、CBC 到 GCM 的 C# 深度实践
· InnoDB为什么不用跳表,Redis为什么不用B+树?
· 记一次 C# 平台调用中因非托管 union 类型导致的内存访问越界
· [EF Core]聊聊“复合”属性
· 那些被推迟的 C# 14 特性及其背后的故事
· 博客园出海记-开篇:扬帆启航
· 记一次 .NET 某汽车控制焊接软件 卡死分析
· 关于布尔类型的变量不要加 is 前缀,被网友们吐槽了,特来完善下
· C#中的多级缓存架构设计与实现深度解析
· 技术人日常避坑手册:高效工作,少踩坑