[51nod1515]明辨是非

Posted Aireen Ye

tags:

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

Description

技术分享组操作,每组操作形式为技术分享.

技术分享时,如果第技术分享变量和第技术分享个变量可以相等,则输出技术分享,并限制他们相等;否则输出技术分享,并忽略此次操作.

技术分享时,如果第技术分享变量和第技术分享个变量可以不相等,则输出技术分享,并限制他们不相等;否则输出技术分享,并忽略此次操作.

Input

输入一个数技术分享表示操作的次数.接下来技术分享行每行三个数技术分享.

Output

对于技术分享行操作,分别输出技术分享技术分享或者技术分享.

Sample Input

3
1 2 1
1 3 1
2 3 0

Sample Output

YES
YES
NO

HINT

技术分享.

Solution

离散化所有的变量.

可以用并查集维护相等的关系,技术分享维护不等的关系.

技术分享时,如果技术分享都不在对方的技术分享中,则可行,按技术分享大小合并它们的父亲和技术分享;

技术分享时,如果技术分享,把技术分享分别插入对方的技术分享中.

#include<set>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 200005
using namespace std;
int a[N],f[N],x[N],y[N],p[N],n,m;
set<int> s[N];
set<int>::iterator l;
inline int gf(int k){
    if(f[k]==k) return k;
    return f[k]=gf(f[k]);
}
inline int search(int k){
    int l=1,r=m,mid;
    while(l<r){
        mid=(l+r)>>1;
        if(a[mid]<k) l=mid+1;
        else r=mid;
    }
    return l;
}
inline void init(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        scanf("%d%d%d",&x[i],&y[i],&p[i]);
        a[++m]=x[i];a[++m]=y[i];
    }
    sort(a+1,a+1+m);
    for(int i=1;i<=n;++i){
        x[i]=search(x[i]);
        y[i]=search(y[i]);
    }
    for(int i=1;i<=m;++i) f[i]=i;
    for(int i=1,j,k,q;i<=n;++i){
        j=gf(f[x[i]]);k=gf(f[y[i]]);
        if(!p[i]){
            if(j==k) puts("NO");
            else{
                puts("YES");
                s[j].insert(k);
                s[k].insert(j);
            }
        }
        else{
            if(j==k) puts("YES");
            else if(s[j].count(k)||s[k].count(j)) puts("NO");
            else{
                puts("YES");
                if(s[j].size()>s[k].size()){
                    q=j;j=k;k=q;
                }
                f[j]=k;
                for(l=s[j].begin();l!=s[j].end();++l){
                    q=gf(*l);
                    s[*l].erase(j);
                    s[q].insert(k);
                    s[k].insert(q);
                }
                s[j].clear();
            }
        }
    }
}
int main(){
    freopen("judge.in","r",stdin);
    freopen("judge.out","w",stdout);
    init();
    fclose(stdin);
    fclose(stdout);
    return 0;
}

以上是关于[51nod1515]明辨是非的主要内容,如果未能解决你的问题,请参考以下文章

题解51nod1515——明辨是非

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

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

[題解]51nod_1515_明辨是非

51nod 1515 明辨是非 并查集+set维护相等与不等关系

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