51nod-1515 明辨是非——并查集
Posted i am back
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod-1515 明辨是非——并查集相关的知识,希望对你有一定的参考价值。
给n组操作,每组操作形式为x y p。
当p为1时,如果第x变量和第y个变量可以相等,则输出YES,并限制他们相等;否则输出NO,并忽略此次操作。
当p为0时,如果第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 明辨是非——并查集的主要内容,如果未能解决你的问题,请参考以下文章