【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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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;
} 

你可能感兴趣的:(算法题目,并查集,哈希算法,算法,c++)