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

227 篇文章 3 订阅
134 篇文章 0 订阅

最近的题目都太难了啊,于是在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\n",x==y);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值