NOI2015 程序自动分析

时间:2020-12-24 20:42:24

Luogu

写个并查集来维护就行了。先合并所有相等的变量,如果有两个不相等的变量相等,那么就输出NO。注意得先合并所有相等的变量,再来判断。因为如果两个操作一起搞的话,可能会有两个变量在某次查询的时候不相等,但后面被合并了。还有就是\(i,j\)贼jb大,要离散化一下。

#include <bits/stdc++.h>

const int max_n=1e5+5;

int T,N,tot;
int father[max_n<<1],num[max_n<<1],A[max_n<<1],X[max_n],Y[max_n],Z[max_n];

inline int read()
{
register int x=0;
register char ch=getchar();
while(!isdigit(ch))
ch=getchar();
while(isdigit(ch))
{
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
return x;
}

int find_father(int x)
{
return (father[x]==x)?x:father[x]=find_father(father[x]);
}

void merge(int x,int y)
{
father[find_father(x)]=find_father(y);
}

bool is_same(int x,int y)
{
return find_father(x)==find_father(y);
}

int main()
{
int flag;
T=read();
while(T--)
{
flag=tot=0;
N=read();
for(int i=1;i<=N;++i)
{
X[i]=read(),Y[i]=read(),Z[i]=read();
num[i]=X[i],num[i+N]=Y[i];
}
std::sort(&num[1],&num[(N<<1)+1]);
for(int i=1;i<=N<<1;++i)
if(num[i]^num[i-1]) A[++tot]=num[i];
for(int i=1;i<=tot;++i)
father[i]=i;
for(int i=1;i<=N;++i)
if(Z[i]) merge(std::lower_bound(&A[1],&A[1+tot],X[i])-A,std::lower_bound(&A[1],&A[1+tot],Y[i])-A);
for(int i=1;i<=N;++i)
{
if(!Z[i] && is_same(std::lower_bound(&A[1],&A[1+tot],X[i])-A,std::lower_bound(&A[1],&A[1+tot],Y[i])-A))
{
puts("NO");
flag=1;
break;
}
}
if(!flag) puts("YES");
}
return 0;
}