Jzoj4736 漆黑列车载运数个谎言(GOSICK系列)

最近的题目都太难了啊,于是在oj上面瞎找题目来切

正好这一套题目名都比较优雅于是就选了这一套


这个看起来十分像并查集

没错,我们发现,如果两个结论互为逆反命题,那么这两个结论等价

而且一个逆命题的逆命题或者是反命题的反命题就是自己

所以我们发现,1和2是等价的,这就如同敌人的敌人是朋友一般(一道很经典的题了)

我们将0视为两个人是朋友,1,2表示两个人是敌人

询问就等价于两个人是否是朋友(那干什么要两种询问,-_-||)

经典的并查集拆点做法

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 1000010
using namespace std;
int f[N<<1],n,m;
inline int gf(int x){ return f[x]==x?x:f[x]=gf(f[x]); }
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n<<1;++i) f[i]=i;
	for(int o,x,y,dx,dy;m--;){
		scanf("%d%d%d",&o,&x,&y);
		dx=gf(x+n); dy=gf(y+n);
		x=gf(x); y=gf(y);
		if(o==0){
			if(x!=y) f[x]=y;
			if(dx!=dy) f[dx]=dy;
		} else if(o==1||o==2){
			if(x!=dy)f[x]=dy;
			if(dx!=y)f[dx]=y;
		} else printf("%d
",x==y);
	}
}

原文地址:https://www.cnblogs.com/Extended-Ash/p/9477294.html