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

被折叠的 条评论
为什么被折叠?



