【并查集/离散化】洛谷P1955 程序自动分析

思路是先把等号的两个数用并查集连起来。

再扫一遍不等号,如果这两个数在同一集合内,就NO,返回。

如果成功扫完了,输出YES。

但是这题数据这么大,必须离散化。

lower_bound是个好东西啊,找到第一个不小于某个数的位置,这样就能方便我们进行离散化了。

楼下的dalao都说是普及组难度,本蒟蒻真是服了。

我拿普一的时候数据结构还没入门呢!

下面是代码,写的不算太丑吧

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <stack>
#include <ctime>
#include <cmath>
#include <map>
#include <set>
#include <queue>
#include <list>
#include <vector>
#define rep(i,m,n) for(int i=m;i<=n;i++)
#define dop(i,m,n) for(int j=m;j>=n;j--)
#define lowbit(x) (x&(-x))
using namespace std;
const int maxn=100010;
long long f[2*maxn+100];
long long n,T,a[maxn],b[maxn],c[maxn],e[2*maxn];
void cch(){
    rep(i,1,2*n) f[i]=i;
}
int find(int x){
    return f[x]==x?x:f[x]=find(f[x]);
}
void merge(int x,int y){
    f[find(y)]=f[find(x)];
}
bool ask(int x,int y){
    return find(x)==find(y);
}
void Work(){
    int tmp=0;
    cin>>n;
    cch();
    memset(e,0,sizeof(e));
    rep(i,1,n){
       cin>>a[i]>>b[i]>>c[i];
       e[++tmp]=a[i];
       e[++tmp]=b[i];
    }
    sort(e+1,e+tmp+1);
    rep(i,1,n)
       if(c[i])
         merge(lower_bound(e+1,e+tmp+1,a[i])-e,lower_bound(e+1,e+tmp+1,b[i])-e);
    rep(i,1,n)
       if(!c[i])
         if(ask(lower_bound(e+1,e+tmp+1,a[i])-e,lower_bound(e+1,e+tmp+1,b[i])-e)){
           printf("NO\n");
           return ;
         }
    printf("YES\n");
    return ;
}
int main(){
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin>>T;
    while(T--)
      Work();
    return 0; 
}

点赞