-
相等有传递性
-
不相等没有传递性
-
使用 并查集 维护两两之间相等的数字
-
对每个祖先开一个 , 当两个数字不能相等时, 他们的祖先互相记录对方的祖先.
考试的时候忘了合并 …
- 判断是否相等时, 直接看两者的 祖先 中有没有记录对方 .
若两者可以相等, 则 启发式合并 二者 .
判断不等直接看祖先是否相等就可以了 .
所谓启发式合并, 就是将 小的合并到 大的 .
没什么好说的 .
#include<bits/stdc++.h>
#define reg register
int read(){
char c;
int s = 0, flag = 1;
while((c=getchar()) && !isdigit(c))
if(c == '-'){ flag = -1, c = getchar(); break ; }
while(isdigit(c)) s = s*10 + c-'0', c = getchar();
return s * flag;
}
const int maxn = 1e5 + 5;
int N;
int cnt;
int F[maxn];
std::map <int, int> Mp;
std::set <int> st[maxn];
int Find(int x){ return F[x]==x?x:F[x]=Find(F[x]); }
void Work(){
int x = read(), y = read(), p = read();
if(!Mp.count(x)) Mp[x] = ++ cnt, F[cnt] = cnt;
if(!Mp.count(y)) Mp[y] = ++ cnt, F[cnt] = cnt;
int t1 = Mp[x], t2 = Mp[y];
if(p == 1){
int f1 = Find(t1), f2 = Find(t2);
if(f1 == f2){ printf("YES
"); return ; }
if(st[f1].count(f2) || st[f2].count(f1)){ printf("NO
"); return ; }
if(st[f1].size() > st[f2].size()) std::swap(f1, f2);
for(reg std::set<int>::iterator i = st[f1].begin(); i != st[f1].end(); i ++) st[f2].insert(*i), st[*i].insert(f2);
F[f1] = f2;
printf("YES
");
}else{
int f1 = Find(t1), f2 = Find(t2);
if(f1 == f2){ printf("NO
"); return ; }
st[f1].insert(f2), st[f2].insert(f1);
printf("YES
");
}
}
int main(){
N = read();
for(reg int i = 1; i <= N; i ++) Work();
return 0;
}