【AcWing 237. 程序自动分析】并查集+离散化

题目链接

题意:

给你n个关系, 每个关系都是由x,y,st组成的,当st = 1时表示的是x和y相等,当st = 0是表示的是x和y不相等,现在给出你这n个关系,问这些关系是否有相互矛盾的关系。

分析:

相等关系可以看作是并查集在一个集合内,不相等关系可以看作是并查集不在一个集合内,输入的x和y上限是1e9,但是最多是2e5个数,那么咱们就可以进行离散化,因为这个对顺序没有什么规定,不属于保序离散化,所以说可以用map来进行离散化,这里用unordered_map就会比map快不少了,亲测,用的普通map就TLE了,但是用unordered_map就过了,离散化完成之后就可以进行判断了,咱们采用先看相等关系再看不等关系的策略,因为这个输入顺序其实没啥用,而且相等关系是不会出现错误的,后面再判断不相等关系即可,下面具体请看代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<map>
#include<stack>
#include<cstdlib>
#include<climits>
#include<unordered_map>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef unsigned long long ull;
const int mod = 1e9+7;
const int N = 100010;
unordered_map<int,int> mp;
struct node{
	int x,y,st;
}g[N];
int pa[N+N];
int find(int x){
	if(x != pa[x]) pa[x] = find(pa[x]);
	return pa[x];
}
int main(){
	int _;
	cin>>_;
	while(_--){
		int n;
		mp.clear();
		scanf("%d",&n);
		int cnt = 0;
		for(int i=1;i<=n;i++){
			scanf("%d%d%d",&g[i].x,&g[i].y,&g[i].st);
			if(!mp[g[i].x]) mp[g[i].x] = ++cnt;
			if(!mp[g[i].y]) mp[g[i].y] = ++cnt;
		}
		for(int i=1;i<=cnt;i++) pa[i] = i;
		int flag = 1;
		for(int i=1;i<=n;i++){
			int x = mp[g[i].x],y = mp[g[i].y];
			if(g[i].st == 1){
				pa[find(x)] = find(y);
			}
		}
		for(int i=1;i<=n;i++){
			int x = mp[g[i].x],y = mp[g[i].y];
			if(g[i].st == 0){
				if(find(x) == find(y)){
					flag = 0;
					break;
				}
			}
		}
		if(flag) puts("YES");
		else puts("NO");
	}
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宇智波一打七~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值