<h1>题目描述</h1>
<h2>题目描述</h2>
在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足。
考虑一个约束满足问题的简化版本:假设$ x1,x2,x3 cdots
代表程序中出现的变量,给定n个形如$ xi=xj $或$ xi \neq xj $的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所有约束条件同时被满足。例如,一个问题中的约束条件为:$ x1=x2,x2=x3,x3=x4,x4 \neq x1 $,这些约束条件显然是不可能同时被满足的,因此这个问题应判定为不可被满足。
现在给出一些约束满足问题,请分别对它们进行判定。
<h2>输入输出格式</h2>
<h3>输入格式</h3>
从文件 frog.in中读入数据。
输入文件的第1行包含1个正整数t,表示需要判定的问题个数。注意这些问题之间是相互独立的。
对于每个问题,包含若干行:
第1行包含1个正整数n,表示该问题中需要被满足的约束条件个数。接下来n行,每行包括3个整数$ i,j,e $,描述1个相等/不等的约束条件,相邻整数之间用单个空格隔开。若$ e=1 $,则该约束条件为$ xi=xj $;若$ e=0 $,则该约束条件为$ xi \neq xj $;
<h2>输出格式</h2>
输出到文件 frog.out 中。
输出文件包括t行。
输出文件的第 k行输出一个字符串“ YES” 或者“ NO”(不包含引号,字母全部大写),“ YES” 表示输入中的第k个问题判定为可以被满足,“ NO” 表示不可被满足。
<h2>输入输出样例</h2>
<h3>输入样例</h3>
2 2 1 2 1 1 2 0 2 1 2 1 2 1 1
<h3>输出样例</h3>
NO YES
<h1>题目分析</h1>
这一题可以用并查集做。我们将$ i,j $ 离散化后,如果相等,就合并这两个集合,如果不相等,就判断他们是否在一个集合内。当找到不符合前面条件的条件是,输出即可
用到的算法是 并查集和 离散化
<h1>样例代码</h1>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 600000 + 5;
#define LL long long
#define Data pair<LL,LL>
int f[MAXN],n;
Data a[MAXN];
int A[MAXN],B[MAXN],e[MAXN];
void init(){
for(int i = 1;i <= 500010;i++)
f[i] = i;
memset(e,0,sizeof(e));
memset(A,0,sizeof(A));
memset(a,0,sizeof(a));
}
int find(int x){
if(x == f[x])
return x;
return f[x] = find(f[x]);
}
void Union(int x,int y){
f[find(x)] = find(y);
}
bool pd(int x,int y){
return (find(x) == find(y));
}
bool cmp(Data x,Data y){
return (x.first > y.first);
}
void lisan(Data a[],int A[]){
int tot = 0;
sort(a + 1,a + n*2 + 1,cmp);
for (int i = 1;i <= n*2;i++)
{
if (i==1 || a[i].first != a[i-1].first) tot++;
A[a[i].second] = tot;
}
}
void work(){
scanf("%d",&n);
bool flag=0;
init();
for (int i=1;i<=n;i++)
{
LL aa,bb;
scanf("%lld%lld%d",&aa,&bb,&e[i]);
a[i] = make_pair(aa,i);
a[i + n] = make_pair(bb,i+n);
}
lisan(a,A);
for (int i=1;i<=n;i++) B[i]=A[n+i];
for (int i=1;i<=n;i++)
if (e[i]) Union(A[i],B[i]);
for (int i=1;i<=n;i++)
if (!e[i])
if (pd(A[i],B[i])){
flag=1;break;
}
if(!flag) printf("YESn");
else printf("NOn");
}
int main(){
int T;
scanf("%d",&T);
while(T--) work();
return 0;
}