>Link
ybtoj程序自动分析
>Description
给出几个要么是 x i = x j x_i=x_j xi=xj,要么是 x i ≠ x j x_i≠x_j xi=xj的条件,判断这几个条件是否能同时存在(合法)?
>解题思路
很明显需要用并查集来实现。首先将全部为相等条件的两个数并到一个集,在一个个看条件为不相等的两个数,这两个数如果在一个集合里说明不合法
由于题目给的数据:
1
≤
n
≤
1
0
6
1≤n≤10^6
1≤n≤106,
1
≤
i
,
j
≤
1
0
9
1≤i,j≤10^9
1≤i,j≤109
如果我们直接把
i
,
j
i,j
i,j处理加进并查集,数组空间是不够大的
所以我们这里要做一个离散化处理下
>代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 1000010
using namespace std;
struct node
{
int x, bh;
} p[2 * N];
int T, n, a, b, c[2 * N], cnt, e[N];
bool cmp_x (node aa, node bb) {return aa.x < bb.x;}
bool cmp_bh (node aa, node bb) {return aa.bh < bb.bh;}
int find (int now)
{
if (now == c[now]) return now;
return c[now] = find (c[now]);
}
void work ()
{
cnt = 0; //清零
for (int i = 1; i <= 2000000; i++) c[i] = i;
scanf ("%d", &n);
for (int i = 1; i <= n; i++)
{
cnt++;
scanf ("%d", &p[cnt].x), p[cnt].bh = i;
cnt++;
scanf ("%d", &p[cnt].x), p[cnt].bh = i;
scanf ("%d", &e[i]);
}
sort (p + 1, p + 1 + cnt, cmp_x);
int pp = p[1].x;
p[1].x = 1;
for (int i = 2; i <= cnt; i++)
{
if (p[i].x == pp) pp = p[i].x, p[i].x = p[i - 1].x;
else pp = p[i].x, p[i].x = p[i - 1].x + 1;
}
sort (p + 1, p + 1 + cnt, cmp_bh); //离散化
for (int i = 1; i <= cnt; i += 2)
if (e[p[i].bh] == 1)
{
int a = find (p[i].x), b = find (p[i + 1].x);
if (a < b) c[b] = a;
else c[a] = b;
}
for (int i = 1; i <= cnt; i += 2)
if (e[p[i].bh] == 0)
{
int a = find (p[i].x), b = find (p[i + 1].x);
if (a == b) {printf ("NO\n"); return;}
}
printf ("YES\n");
}
int main()
{
scanf ("%d", &T);
while (T--) work ();
return 0;
}