1955 程序自动分析

这篇博客探讨了一种使用并查集和离散化解决程序自动分析中约束条件判断的问题。通过离散化处理大数据以去除重复,再利用并查集进行集合操作,解决加边和删边的排序问题。文章介绍了具体的算法实现,包括排序、查找和集合操作,并通过示例解释了不合理的输出情况。在实践中,作者遇到一些挑战,但最终找到了解决方案。

1955 程序自动分析

练习并查集…
并查集的板子,一看到给出约束条件最后进行判断,就是一个并查集啦(危
注意了,这里需要用到离散化,因为数据非常大,离散化就是一个去重的过程,这就是为什么该是黄题结果标的绿题…
比如1 2 1、1 2 0表示的是2和1相等,2又和0相等,显然不合理,输出NO
x=y的操作类似于并查集加边,x≠y的操作类似于并查集的删边,需要先加边后删边,需要把指令进行一个排序
这里还会运用到二分,用来寻找元素的位置,然后再开始并查集,还是挺水的吧,结果我提交了20次…

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int SIZE=100007;
int T;int n;
struct node{
	int x,y,opt;
}a[SIZE*2];
int x[SIZE*2];
int tot,end[SIZE*2]; 
bool flag=0;
int f[SIZE*2];
bool cmp(node a,node b)
{
	return a.opt>b.opt;
}
int findd(int x)
{
	return f[x]==x?x:f[x]=findd(f[x]);
}
int sol(int x)//查找x的位置 
{
	int l=1,r=tot;
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(end[mid]==x) return mid;
		if(x>end[mid]) l=mid+1;
		else r=mid-1;
	}
}
int main()
{
	cin>>T;
	while(T--)
	{
		tot=0;
		flag=0;
		cin>>n;
		for(register int i=1;i<=n;i++)
		{
			cin>>a[i].x>>a[i].y>>a[i].opt;
			x[i*2-1]=a[i].x;
			x[i*2]=a[i].y;//为离散化做准备 
		}
		sort(x+1,x+2*n+1);
		for(register int i=1;i<=2*n;i++)//离散化 
		{
			if(x[i]!=x[i-1])//去重 
			{
				end[++tot]=x[i];
			}
		}
		for(register int i=1;i<=tot;i++) f[i]=i;//集合初始化 
		sort(a+1,a+n+1,cmp);
		for(register int i=1;i<=n;i++)
		{
			if(a[i].opt)
			{
				int t1=findd(sol(a[i].x)),t2=findd(sol(a[i].y));
				if(t1!=t2) f[t1]=t2;
			}
			else 
			{
				int t1=findd(sol(a[i].x)),t2=findd(sol(a[i].y));
				if(t1==t2)
				{
					cout<<"NO"<<endl;
					flag=1;
					break;
				}
			}
		}
		if(!flag) cout<<"YES"<<endl;
	}
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值