扩展域并查集
扩展域并查集就是指:将并查集的状态由基本的:几个元素属于朋友,则放入并查集;
扩展为更多状态。
更多通过题目来理解把。
P2024 [NOI2001] 食物链
题意
动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形。
A 吃 B,B 吃 C,C 吃 A。
现有 N 个动物,以 1∼N 编号。
每个动物都是 A,B,C 中的一种,但是我们并不知道它到底是哪一种。
有人用两种说法对这 N 个动物所构成的食物链关系进行描述:
第一种说法是 1 X Y,表示 X 和 Y 是同类。
第二种说法是 2 X Y,表示 X 吃 Y。
此人对 N 个动物,用上述两种说法,一句接一句地说出 K 句话,这 K 句话有的是真的,有的是假的。
当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
当前的话与前面的某些真的话冲突,就是假话;
当前的话中 X 或 Y 比 N 大,就是假话;
当前的话表示 X 吃 X,就是假话。
你的任务是根据给定的 N 和 K 句话,输出假话的总数。
思路
可以将状态分为:
同类,食物,天敌
也就是说,将状态扩展为:
-
同类:如果a和b是同一类,则将a和b合并到一个并查集
-
食物:如果a是b的食物,则将a和b合并到一个并查集
-
天敌:如果a是b的天敌,则将a和b合并到一个并查集
将状态扩展后,相应的合并也要修改。
-
如果a和b是同类,那么
a的天敌、同类、食物也是b的天敌、同类、食物。 -
如果a是b的天敌,那么
a的天敌是b的食物;
a的同类是b的天敌;
a的食物是b的同类。
然后再判断题目的几个条件
当前的话中 X 或 Y 比 N 大,就是假话;
直接判断即可
当前的话表示 X 吃 X,就是假话。
当输入为同类时,直接判断即可
当前的话与前面的某些真的话冲突,就是假话;
如果输入a是b的同类,那么需要确定以下条件,才能算对
- a的天敌没有b
- a的食物没有b
不需要判断:a的同类是不是b的同类
如果输入a是b的天敌,那么需要确定以下条件,才能算对
- a的同类没有b
- a的天敌没有b
不需要判断:a的食物是不是b的同类
实现
就是用3倍的并查积的存各种动物的关系:一倍存本身,二倍存食物,三倍存天敌。
每次维护三个并查积的关系就可以了
具体看代码吧
代码
#include <bits/stdc++.h> using namespace std; #define int long long #define pii pair<int, int> const int N =1e5 + 10; int fa[N*3]; int n,m; int find(int x){ if(fa[x]!=x) fa[x]=find(fa[x]); return fa[x]; } void slove() { cin>>n>>m; for(int i=1;i<=3*n;++i) fa[i]=i; int ans=0; int x1, x2, x3, y1, y2, y3; for(int i=1;i<=m;i++){ int a,x,y;cin>>a>>x>>y; if(x>n || y>n){ ans++; continue; } x1 = find(x);//同类 x2 = find(x + n);//食物 x3 = find(x + n * 2);//天敌 y1 = find(y); y2 = find(y + n); y3 = find(y + n * 2); if(a==1){ //如果1是2的天敌或猎物,显然为谎言 if(x2==y1 || x3==y1){ ans++; continue; } fa[x1]=y1 , fa[x2]=y2 , fa[x3]=y3; } else{ //如果1是2的同类或猎物,显然为谎言 if(x1==y1 || x3==y1){ ans++; continue; } fa[x2] = y1 , fa[x3]=y2 , fa[x1]=y3; } } cout<<ans<<endl; } signed main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int t = 1; // cin >> t; while (t--) slove(); return 0; }
本文作者:kingwzun
本文链接:https://www.cnblogs.com/kingwz/p/16650762.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2021-09-02 Java基础语法