【ybtoj】【并查集】【例题2】程序自动分析

【例题2】程序自动分析


Link

传送门
题目


解题思路

这题**的要离散化
虽然不是很难,但是有必要在这么模板的题上加个离散化吗,有!必!要!吗!

将 ‘等于’ 和 ‘不等于’ 分开处理
先处理‘等于’,做并查集
再处理‘不等于’,如果‘不等于’的两个点出现在同个集里,说明两个点既 ‘等于’ 又 ‘不等于’,出现不满足


Code

#include <algorithm>
#include <iostream>
#include <cstdio>

using namespace std;

struct demo{
	int s, i, x;
}sor[2001000];
struct DT{
	int x, y, e;
}a[1001000], no[1001000];
int flag, num, T, n, sum; 
int fa[1001000], e, x, y, xx, yy;

bool cmp(const demo&k, const demo&l) {
	return k.s < l.s;
}

int find(int x) {
	if(fa[x] != x) {
		fa[x] = find(fa[x]);
		return fa[x];
	}
	return x;
}

int main() {
	scanf("%d", &T);
	while(T--) {
		scanf("%d", &n);
		for (int i = 1; i <= n * 2; i++)
			fa[i] = i;
		
		flag = 1, num = sum = 0;
		for(int i = 1; i <= n; i++) {
			scanf("%d %d %d", &a[i].x, &a[i].y, &a[i].e);
			sor[++sum].s = a[i].x, sor[sum].i = i, sor[sum].x = 1;
			sor[++sum].s = a[i].y, sor[sum].i = i, sor[sum].x = 2;
		}
		sort(sor + 1, sor + 1 + n * 2, cmp);
		int k = 0;
		for (int i = 1; i <= n * 2; i++) {
			if (sor[i].s != sor[i - 1].s) 
				k++;
			if (sor[i].x == 1) a[sor[i].i].x = k;
				else a[sor[i].i].y = k;
		}   //以上为离散化[○・`Д´・ ○]
		
		for(int i = 1; i <= n; i++) {
			if (a[i].e == 0)  //把‘不等于’提取出来,先不做
				no[++num].x = a[i].x, no[num].y = a[i].y;
			else {  //‘等于’的点做并查集
				xx = find(a[i].x), yy = find(a[i].y);
				if (xx != yy)
					fa[xx] = yy;
			}
		}
		for(int i = 1; i <= num; i++) {
			xx = find(no[i].x), yy = find(no[i].y);
			if (xx == yy) {  //如果两个‘不等于’的点出现在同一集里
				flag = 0;
				break;
			}
		}
		if (flag) printf("YES\n");
		else printf("NO\n");
	}
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值