题意
给定 n 个约束条件,形如:
xi=xj or xi≠xj
问能否满足所有的约束条件,多组数据
PS:i,j 的范围很大,为 109
题解
如果 i,j 很小,那么这道题就很简单,至少比食物链简单很多,直接利用并查集判断即可
当 i,j 很大时,尽管无法直接开个数组存下来,但是 n 很小啊!(相对来说),因此可以离散化所有的i,j ,然后利用离散化后的数据+并查集便可以解决本题
复杂度
O( nlogn )
代码
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#define Rint register int
#define Lint long long int
using namespace std;
const int N=200010;
struct node
{
Lint u,v;
int type;
}p[N];
int f[N],t,n,c;
Lint q[N];
int find(int x)
{
if( x!=f[x] ) f[x]=find( f[x] );
return f[x];
}
int get(Lint x)
{
int l=1,r=c;
while( l<=r )
{
int mid=(l+r)/2;
if( q[mid]>x ) r=mid-1;
else
if( q[mid]<x ) l=mid+1;
else return mid;
}
}
int main()
{
int flg,tmp;
scanf("%d",&t);
while( t-- )
{
scanf("%d",&n);
flg=1,c=0;
for(int i=1;i<=n;i++)
{
scanf("%lld%lld%d",&p[i].u,&p[i].v,&p[i].type);
q[++c]=p[i].u,q[++c]=p[i].v;
}
sort( q+1,q+c+1 );
tmp=c,c=0;
for(int i=1;i<=tmp;i++)
{
q[++c]=q[i];
if( q[i+1]==q[c] && i+1<=tmp ) i++;
}
for(int i=1;i<=c;i++) f[i]=i;
for(int i=1;i<=n;i++)
{
p[i].u=get( p[i].u ),p[i].v=get( p[i].v );
if( p[i].type ) f[find(p[i].u)]=find(p[i].v);
}
for(int i=1;i<=n;i++)
{
if( p[i].type ) continue ;
if( find(p[i].u)==find(p[i].v) ) { flg=0;break ; }
}
if( flg ) printf("YES\n");
else printf("NO\n");
}
return 0;
}