P1955 [NOI2015]程序自动分析 【离散化】【并查集】

链接
题解:
首先是并查集
然后由于 i, j 的范围是[1,1e9],数组不能开这么大,实际上不同数字的个数不会超过2e6,所以离散化
注意:并查集时,先操作所有e=1,再操作所有e=0,
因为
判断答案时,只有出现一种情况时判断为NO,即(fa==fb&&!e)
先操作所有e=1(并)
或者反证,
例:
1 2 0
1 2 1
不是先1后0,会输出YES, 正解NO

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e6+7;
struct node{
    int x,y,e;
}a[maxn];
bool cmp(node tem1,node tem2){
    return tem1.e>tem2.e;
}
int b[maxn],dad[maxn];
int seek(int k){
    return k==dad[k]?k:dad[k]=seek(dad[k]);
}
int main() {
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int bi=1;
        for(int i=1;i<=n;i++){
            scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].e);
            b[bi++]=a[i].x;
            b[bi++]=a[i].y;
        }
        sort(b+1,b+bi);
        int* van=unique(b+1,b+bi);
        for(int i=1;i<=n;i++){
            a[i].x=lower_bound(b+1,van,a[i].x)-b;
            a[i].y=lower_bound(b+1,van,a[i].y)-b;
        }
        //离散化


        //并查集
        sort(a+1,a+n+1,cmp);
        for(int i=1;i<=2*n;i++)
            dad[i]=i;
        int flag=1;
        for(int i=1;i<=n;i++){
            int fa=seek(a[i].x);
            int fb=seek(a[i].y);
            if(fa==fb&&!a[i].e){flag=0;break;}
            if(fa!=fb&&a[i].e){
                dad[fa]=fb;
            }
        }
        if(flag)cout<<"YES"<<endl;
        else cout << "NO" << endl;
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值