程序自动分析--并查集+离散化

ACwing 239

在这里插入图片描述

题目分析:

  • 将相等的合并在同一个集合中,最后再判断 x ! = y x!=y x!=y如果在一个集合中,就不满足约束
  • 由于 x , y 很 大 x,y很大 x,y,需要离散化
  • s o r t sort sort,再 u n i q u e unique unique,再 l o w e r lower lower_ b o u n d bound bound
  • r a n k rank rank是保留字,不要用!!打下划线!!!!

Code:

#include <bits/stdc++.h>
using namespace std;
#define maxn 1000010

int rank_[maxn<<1],m,T,n,x[maxn],sum=0,y[maxn],pd[maxn],d[maxn<<1],top=0,f[maxn<<1];
struct ndoe {
	int u,v;
}st[maxn];

inline void init_() {
	freopen("a.txt","r",stdin);
}

inline int read_() {
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9') {
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9') {
		x=(x<<3)+(x<<1)+c-'0';
		c=getchar();
	}
	return x*f;
}

inline void lisan_() {
	sort(d+1,d+sum+1);
    m=unique(d+1,d+sum+1)-d-1;
	for(int i=1;i<=n;++i) {
		x[i]=lower_bound(d+1,d+m+1,x[i])-d;
		y[i]=lower_bound(d+1,d+m+1,y[i])-d;
	}
}

int find_(int x) {
	if(f[x]==x) return x;
	else return f[x]=find_(f[x]);
}

inline void merge_(int x,int y) {
	int fx=find_(x),fy=find_(y);
	if(fx==fy) return;
	if(rank_[fx]>rank_[fy]) swap(fx,fy);
	f[fx]=fy;
	rank_[fy]=max(rank_[fy],rank_[fx]+1);
}

void readda_() {
	T=read_();
	while(T--) {
		n=read_();
		sum=0;top=0;
		for(int i=1;i<=n;++i) {
			x[i]=read_();y[i]=read_();pd[i]=read_();
			d[++sum]=x[i];d[++sum]=y[i];
		}
		lisan_();
		for(int i=0;i<=m+1;++i) {
			f[i]=i;
			rank_[i]=1;
		}
		for(int i=1;i<=n;++i) {
			if(pd[i]) {
				merge_(x[i],y[i]);
			}
			else {
				st[++top].u=x[i];
				st[top].v=y[i];
			}
		}
		int pdc=0;
		for(int i=1;i<=top;++i) {
			int fx=find_(st[i].u),fy=find_(st[i].v);
			if(fx==fy) {
				printf("NO\n");
				pdc=1;
				break;
			}
		}
		if(pdc) continue;
		else printf("YES\n");
	}
}

int main() {
	init_();
	readda_();
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值