题目链接
https://www.luogu.com.cn/problem/P1955
思路
因为
i
i
i和
j
j
j的最大值可以为
1
e
10
1e10
1e10,所以本题需要先进行离散化处理。
首先,我们处理
e
e
e为
1
1
1的情况,将相等的两个
x
i
x_{i}
xi和
x
j
x_{j}
xj用并查集连接成一块。之后,我们处理
e
e
e为
0
0
0的情况,如果两个
x
i
x_{i}
xi和
x
j
x_{j}
xj不在一个联通块,则继续向下处理,否则直接输出NO。最后,如果没有矛盾,则输出YES。
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 5;
const int inf = 0x3f3f3f3f3f3f3f3f;
int n;
int a[N], b[N], e[N];
struct DSU {
std::vector<int> f, siz;
DSU() {}
DSU(int n) {
init(n);
}
void init(int n) {
f.resize(n);
std::iota(f.begin(), f.end(), 0);
siz.assign(n, 1);
}
int find(int x) {
while (x != f[x]) {
x = f[x] = f[f[x]];
}
return x;
}
bool same(int x, int y) {
return find(x) == find(y);
}
bool merge(int x, int y) {
x = find(x);
y = find(y);
if (x == y) {
return false;
}
siz[x] += siz[y];
f[y] = x;
return true;
}
int size(int x) {
return siz[find(x)];
}
};
void solve()
{
cin >> n;
set<int>st;
for (int i = 1; i <= n; i++)
{
cin >> a[i] >> b[i] >> e[i];
st.insert(a[i]);
st.insert(b[i]);
}
//离散化
map<int, int>mp;
int idx = 0;
for (int val : st)
{
idx++;
mp[val] = idx;
}
for (int i = 1; i <= n; i++)
{
a[i] = mp[a[i]];
b[i] = mp[b[i]];
}
DSU dsu(n * 2 + 1);
for (int i = 1; i <= n; i++)
{
if (e[i] == 1)
{
dsu.merge(a[i], b[i]);
}
}
for (int i = 1; i <= n; i++)
{
if (e[i] == 0)
{
if (dsu.same(a[i], b[i]))
{
cout << "NO" << endl;
return;
}
}
}
cout << "YES" << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int test = 1;
cin >> test;
for (int i = 1; i <= test; i++)
{
solve();
}
return 0;
}