给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或者NOSample Input
3 1 2 1 1 3 1 2 3 0
Sample Output
YES YES NO
题解:
相同的用并查集维护,不相同的用set启发式合并。
#include<bits/stdc++.h> using namespace std; const int maxn=2e5+5; set<int> s[maxn]; set<int>::iterator it; unordered_map<int,int> H; int cnt=0,par[maxn]; int find(int x) { if(x==par[x]) return x; return par[x]=find(par[x]); } void uni_set(int x,int y) { if(x==y) return ; if(s[x].size()>s[y].size()) { for(it=s[y].begin();it!=s[y].end();it++) { s[x].insert(find(*it)); s[find(*it)].erase(y); s[find(*it)].insert(x); } s[y].clear(); par[y]=x; } else { for(it=s[x].begin();it!=s[x].end();it++) { s[y].insert(find(*it)); s[find(*it)].erase(x); s[find(*it)].insert(y); } s[x].clear(); par[x]=y; } } void uni(int x,int y) { if(s[x].find(y)!=s[x].end()) { cout<<"NO"<<endl; return ; } cout<<"YES"<<endl; uni_set(x,y); } int getid(int x)//坐标离散化 { if(H[x]) return H[x]; return H[x]=++cnt; } void spl(int x,int y) { if(x==y) { cout<<"NO"<<endl; return ; } cout<<"YES"<<endl; s[x].insert(y); s[y].insert(x); } void init() { for(int i=0;i<maxn;i++) par[i]=i; } int main() { int n; cin>>n; init(); for(int i=0;i<n;i++) { int x,y,p; cin>>x>>y>>p; x=find(getid(x)); y=find(getid(y)); if(p) uni(x,y); else spl(x,y); } return 0; }