zoukankan      html  css  js  c++  java
  • 吃瓜题1(虚拟分类并查集)

    题意:
    只有两种西瓜,给出一系列信息——两个西瓜同种或异种,询问某两个西瓜的关系。

    题解:
    对于每个节点建立对立节点。
    约束关系:
    A、B相同:使用并查集合并(A、B),合并 (对立A、对立B)
    A、B不同:使用并查集合并(A、对立B),合并( B、对立A)

    若节点x与节点y在同一并查集中,输出1;
    若节点x与y的对立节点在同一个并查集中:输出2;
    否则,不能确定关系,输出3.

    那么,怎么建立对立节点的并查集呢?
    把原并查集长度拓展成两倍,后半段用来表示对立节点。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn = 1e6 + 5;
    int set[maxn * 2];
    
    int findset(int x) {
        if (x == set[x]) return x;
        else return findset(set[x]);
    }
    
    
    void unionset(int x,int y) {
        int fx = findset(x);
        int fy = findset(y);
        if (fx != fy) {
            set[fy] = fx;
        }
    }
    
    int main() {
        int n, m;
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= 2 * n; i++) {
            set[i] = i;
        }
        while (m--) {
            char s[3];
            int x, y, id;
            scanf("%s", s);
            if (s[0] == 'A') {
                scanf("%d%d%d", &x, &y, &id);
                if (id == 1) {
                    unionset(x, y);
                    unionset(x + n, y + n);
                }
                else {
                    unionset(x, y + n);
                    unionset(x + n, y);
                }
            }
            else {
                scanf("%d%d", &x, &y);
                if (findset(x) == findset(y)) printf("1
    ");
                else if (findset(x) == findset(y + n)) printf("2
    ");
                else printf("3
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    Irrlicht入门教程,下载安装运行
    git 命令用法 流程操作
    summernote富文本编辑器的使用
    MVC进行多文件上传
    jQuery中的for循环var与let的区别
    识别图片中文字(百度AI)
    sublime安装 和 插件安装
    nopCommerce电子商务平台 安装教程(图文)
    springMVC 配置和使用
    mysql 一看就会 基本语法
  • 原文地址:https://www.cnblogs.com/romaLzhih/p/9489843.html
Copyright © 2011-2022 走看看