离散化+并查集
复杂度:(O(Tnlogn))
被函数名给坑了,因为二分和并查集都习惯用find函数。。。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 2000010;
struct Edge{
int i, j, e;
bool operator <(const Edge &ed){
return e > ed.e;
}
};
int p[N];
int n;
int k;
vector<int> v;
vector<Edge> edges;
int get(int x){ // 得到值x的位置
int l = 0, r = k - 1;
while(l < r){
int mid = l + r >> 1;
if(v[mid] >= x) r = mid;
else l = mid + 1;
}
return l;
}
int find(int x){
if(p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main(){
int T;
cin >> T;
while(T --){
cin >> n;
v.clear();
edges.clear();
k = 0;
for(int i = 0; i < n; i ++){
int x, y, e;
cin >> x >> y >> e;
v.push_back(x);
v.push_back(y);
edges.push_back({x, y, e});
}
sort(v.begin(), v.end());
sort(edges.begin(), edges.end());
// 去重
for(int i = 0; i < v.size(); i ++)
if(i == 0 || v[i] != v[i - 1]) v[k ++] = v[i];
for(int i = n * 2 - 1; i >= 0; i --) p[i] = i;
int flag = 0;
for(auto t : edges){
int i = get(t.i), j = get(t.j), e = t.e;
if(e) p[find(j)] = find(i);
else if(find(j) == find(i)){
flag = 1;
break;
}
}
if(flag) puts("NO");
else puts("YES");
}
return 0;
}