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

用并查集维护相等关系

用set维护不等关系

count()函数返回个数值

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
#include <stack>
#include <set>
#include <cstdlib>
typedef long long ll;
using namespace std;
const int maxn=1e5+10;
set<int>s[maxn];
set<int>::iterator it;
int n,x[maxn],y[maxn],t[maxn<<1],cnt=0,pre[maxn],p[maxn];
int m;
int sea(int x)
{
    int e,a;
    e=x;
    while(x!=pre[x]) x=pre[x];
    while(e!=x)
    {
        a=pre[e];
        pre[e]=x;
        e=a;
    }
    return x;
}
int _hash(int x)
{
    return lower_bound(t,t+m,x)-t;
}
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d%d",&x[i],&y[i],&p[i]);
        t[cnt++]=x[i];
        t[cnt++]=y[i];
    }
    sort(t,t+cnt);
    m=unique(t,t+cnt)-t;
    for(int i=0;i<m;i++) pre[i]=i;
    for(int i=0;i<n;i++)
    {
        int xx=_hash(x[i]);int _x=sea(xx);
        int yy=_hash(y[i]);int _y=sea(yy);
        if(!p[i])
        {
            if(_x==_y) printf("NO\n");
            else
            {
                printf("YES\n");
                s[_x].insert(_y);
                s[_y].insert(_x);
            }
        }
        else
        {
            if(_x==_y) printf("YES\n");
            else if(s[_x].count(_y)||s[_y].count(_x)) printf("NO\n");
            else
            {
                printf("YES\n");
                if(s[_y].size()>s[_x].size()) swap(_y,_x);//没有判断会Tle
                pre[_y]=_x;
                for(it=s[_y].begin();it!=s[_y].end();++it)
                {
                    int h=sea(*it);//这里
                    s[h].insert(_x);//   很重要
                    s[_x].insert(h);
                }
            }
        }
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值