51nod-1515 明辨是非——并查集

Posted i am back

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod-1515 明辨是非——并查集相关的知识,希望对你有一定的参考价值。

n组操作,每组操作形式为x y p

p1时,如果第x变量和第y个变量可以相等,则输出YES,并限制他们相等;否则输出NO,并忽略此次操作。

p0时,如果第x变量和第y个变量可以不相等,则输出YES,并限制他们不相等 ;否则输出NO,并忽略此次操作。

Input
输入一个数n表示操作的次数(n<=1*10^5)
接下来n行每行三个数x,y,p(x,y<=1*10^8,p=0 or 1)
Output
对于n行操作,分别输出n行YES或者NO
Input示例
3
1 2 1
1 3 1
2 3 0
Output示例
YES
YES
NO

这题目描述实在是很迷,看了半天才明白,一共三种关系,相等,不相等和不确定,只有YES操作会改变不确定关系。
用set来维护限制不相等的数,用并查集维护限制相等的数,两个数从不确定到不相等,互相插入对方的set;两个数从不确定到相等,改变他们的父结点,默认将小的那个集合的父结点改成大的,就是大吃小的意思。
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <set>
 4 #include <map>
 5 
 6 using namespace std;
 7 
 8 const int MAXN = 2e5 + 5;
 9 
10 int n, cnt = 1,f[MAXN];
11 set<int> nt[MAXN];
12 map<int, int> eq;
13 
14 int find(int x)
15 {
16     return f[x] == x ? x : f[x] = find(f[x]);
17 }
18 
19 int main()
20 {
21     //freopen("in.txt","r",stdin);
22     cin>>n;
23     n +=5;
24     for (int i = 1; i <= n; i++)
25     {
26         f[i] = i;
27     }
28     n -=5;
29     
30     int x, y, p;
31     while (n--)
32     {
33         cin>>x>>y>>p;
34         if (eq[x])//计数标号 
35         {
36             x = eq[x];
37         }
38         else
39         {
40             ++cnt;
41             eq[x]=cnt;
42             x=cnt;
43         }
44         if (eq[y])
45         {
46             y = eq[y];
47         }
48         else
49         {
50             ++cnt;
51             eq[y]=cnt;
52             y=cnt;
53         }
54         int u = find(x), v = find(y);
55         if (p == 1)//限制相等 
56         {
57             if (nt[u].count(v)) //限制不相等
58             {
59                 cout<<"NO"<<endl;
60             }
61             else if (u != v)    //未限制但并未相等
62             {
63                 if (nt[u].size() > nt[v].size())
64                 {
65                     swap(u, v);
66                 }
67                 f[u] = v;
68                 set<int>::iterator it;
69                 for (it = nt[u].begin(); it != nt[u].end(); it++)
70                 {
71                     nt[*it].insert(v);
72                     nt[v].insert(*it);
73                 }
74                 cout<<"YES"<<endl;
75             }
76             else
77             {
78                 cout<<"YES"<<endl;
79             }
80         }
81         else//限制不相等 
82         {
83             if (u == v)
84             {
85                 cout<<"NO"<<endl;
86             }
87             else
88             {
89                 nt[u].insert(v);
90                 nt[v].insert(u);
91                 cout<<"YES"<<endl;
92             }
93         }
94     }
95 
96     return 0;
97 }

 

以上是关于51nod-1515 明辨是非——并查集的主要内容,如果未能解决你的问题,请参考以下文章

51nod-1515 明辨是非——并查集

51nod 1515 明辨是非 并查集 + set + 启发式合并

51Nod 1515(并查集set离散化)

51 nod 1515 明辨是非(并查集合并)

[51nod1515]明辨是非

题解51nod1515——明辨是非