237. 程序自动分析 并查集 + 离散化

题目

在这里插入图片描述

题解思路

数据范围太大 开不了那么大的数组(最大1e8) 所以我们进行离散化
使用<unordered_map>进行离散实现 O(1)的查找(推荐map是logn级别的查找)
可以先对相等的进行合并
再对不相等的进行判断

因为定义相等是不会影响后面不相等的情况的 。

因为如果相等不对 我们假定他正确 不相等肯定不对 依然可以推出答案 不影响最后的答案

而且这题要开两倍空间 (WA了2次)
两个数可能全部都不一样

AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
#include <unordered_map>
using namespace std;

const  int  INF =  0x3f3f3f3f;


unordered_map <int , int > h;

struct node
{
    int i , j , e ;
}q[100100];
int a[200100];
int find2(int x )
{
    if ( x != a[x] )
        a[x] = find2(a[x]);
    return a[x];
}

void uio (int x ,int y )
{
    int fx = find2(x) ;
    int fy = find2(y) ;
    if ( fx != fy )
    {
        a[fy] = fx ;
    }
}
int main ()
{
    ios::sync_with_stdio(false);
    int T;
    cin >> T ;
    while( T-- )
    {
        h.clear();
        int n, pit = 1 ;
        cin>>n;
        for (int i = 1 ; i <= n ; i++ )
        {
            int t1,t2,t3;
            cin>>t1>>t2>>t3;
            if ( h.count(t1) == 0 )
            {
                h[t1] = pit ;
                pit++;
            }
            if ( h.count(t2) == 0 )
            {
                h[t2] = pit ;
                pit++;
            }
            q[i] = { h[t1] , h[t2] , t3 };
        }
        for (int i = 1 ; i <= pit ; i++ )  a[i] = i ;
        for (int i = 1 ; i <= n ; i++ )
        {
            if ( q[i].e == 1 )
            {
                uio( q[i].i , q[i].j );
            }
        }
        int book = 1 ;
        for (int i = 1 ; i <= n ; i++ )
        {
            if ( q[i].e == 0 )
            {
                if ( find2(q[i].i) == find2(q[i].j) )
                {
                    book = 0 ;
                    break;
                }
            }
        }
        if (book)
        {
            cout<<"YES\n";
        }else
        {
            cout<<"NO\n";
        }

    }
    return 0 ;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值