给n组操作,每组操作形式为x y p。
当p为1时,如果第x变量和第y个变量可以相等,则输出YES,并限制他们相等;否则输出NO,并忽略此次操作。
当p为0时,如果第x变量和第y个变量可以不相等,则输出YES,并限制他们不相等 ;否则输出NO,并忽略此次操作。
输入
输入一个数n表示操作的次数(n<=1*10^5)
接下来n行每行三个数x,y,p(x,y<=1*10^8,p=0 or 1)
输出
对于n行操作,分别输出n行YES或者NO
输入样例
3
1 2 1
1 3 1
2 3 0
输出样例
YES
YES
NO
思路:
由于输入数据数值太大,因此需要用map将每个输入值映射到从1开始的连续值。
对于互斥的情况,在每个值安排一个set结构来记录与之互斥的值。
对于相同的情况,用并查集进行合即可,合并时将互斥数量小的合并到互斥数量大的,并且拷贝原来的互斥值。
#include <cstdio>
#include <set>
#include <map>
using namespace std;
const int MAXN = 2e5 + 10;
int n, num = 1;
int fa[MAXN];
int x, y, p;
set<int> dif[MAXN];
map<int, int> table;
int find(int x)
{
if (x != fa[x])
{
fa[x] = find(fa[x]);
}
return fa[x];
}
int main()
{
scanf("%d", &n);
int size = n << 1;
for (int i = 1; i <= size; i++)
{
fa[i] = i;
}
while (n--)
{
scanf("%d%d%d", &x, &y, &p);
map<int, int>::iterator it = table.find(x);
if (it != table.end())
{
x = table[x];
}
else
{
table[x] = num;
x = num;
num++;
}
it = table.find(y);
if (it != table.end())
{
y = table[y];
}
else
{
table[y] = num;
y = num;
num++;
}
x = find(x);
y = find(y);
if (p == 1)
{
set<int>::iterator it = dif[x].find(y);
if (it != dif[x].end())
{
puts("NO");
}
else if (x == y)
{
puts("YES");
}
else
{
if (dif[x].size() > dif[y].size())
{
swap(x, y);
}
fa[x] = y;
for (it = dif[x].begin(); it != dif[x].end(); it++)
{
dif[*it].insert(y);
dif[y].insert(*it);
}
puts("YES");
}
}
else
{
if (x == y)
{
puts("NO");
}
else
{
dif[x].insert(y);
dif[y].insert(x);
puts("YES");
}
}
}
return 0;
}