人人都是好朋友(离散化 + 并查集)

在这里插入图片描述
在这里插入图片描述
思路:并查集基本操作了。。。c为1的先把他们并到同一个集合中,然后再检查c=0的情况,如果他们在同一个集合c又等于0说明矛盾。做这题的时候,出现好多小问题(上次写并查集是去年),首先因为输入量很大,cin会超时,要用scanf,其次因为每次读入两个点所以maxn需要开两倍。就这个两个坑。另外注意到b=1e9这个数很多,开不了这么大,所以需要提前离散化一下。
代码:

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e6 + 7;
typedef long long int ll;
struct node{
    int a,b,c;
    node(){}
    node(int a,int b,int c):a(a),b(b),c(c){};
}ans[maxn];
int res[maxn << 1];
int f[maxn << 1];
int find(int x){
    return f[x] == x? x : f[x] = find(f[x]);
}
void solved(){
    int t;
    for(scanf("%d",&t);t;t--){
        int n; scanf("%d",&n);
        int cnt = 0;
        for(int i = 1; i  <= n * 2 ; i++)f[i] = i;
        for(int i = 1; i <= n; i++){
            int x,y,z;scanf("%d%d%d",&x,&y,&z);
            res[++cnt] = x;
            res[++cnt] = y;
            ans[i] = {x,y,z};
        }
        sort(res + 1,res + 1 + cnt);
        int len = unique(res + 1,res + 1 + cnt) - (res + 1);
        bool flag = true;
        for(int i = 1; i <= n; i++){
            int u = ans[i].a;
            int v = ans[i].b;
            u = lower_bound(res + 1, res + 1 + len,u) - res;
            v = lower_bound(res + 1, res + 1 + len,v) - res;
            if(ans[i].c == 1){
                int fa = find(u);
                int fb = find(v);
                if(fa != fb)f[fa] = fb;
            }else{
                if(find(u) == find(v))flag = false;
            }
        }
        if(flag)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
}
int main(){
    solved();
    return 0;
}
发布了175 篇原创文章 · 获赞 19 · 访问量 7900

猜你喜欢

转载自blog.csdn.net/weixin_43736492/article/details/105610915