ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

种类并查集

2021-02-23 21:03:57  阅读:214  来源: 互联网

标签:emerge ch 题意 查集 同类 include find 种类


传送门

食物链

题意:

有三种动物,其食物链形成一个环,即A吃B,B吃C,C吃D。

现在有n个动物,每个动物都属于ABC中的一种,给你k个描述,判断这k种描述的真假,求出假话的总数。

每次描述输入三个数字d,x, y。

d = 1时,表示X和Y是同类

d = 2时,表示X吃Y

思路:

对于每个动物,都有三种可能,可能是A,可能是B,可能是C

所以我们开三倍的数组,将一个数组分成三份来判断——1 到 n是假设一,n + 1 到n * 2是假设二,n * 2 + 1 到 n * 3是假设三

1A 2A 3A

1B 2B 3B

1C 2C 3C

假设1是A

当d=1时,说明2和1是同类,则2就是A。

我们只需要判断1A和2A是不是同类即可

当d=2时,说明1吃2,根据题意,A吃B,所以2是B。

我们只需要判断1A和2B是不是同类即可

假设1是B

当d=1时,说明2和1是同类,则2就是B

我们就判断1B和2B是不是同类即可

当d=2时,说明1吃2,根据题意,B吃C,所以2是C

我们只需要判断1B和2C是不是同类即可

假设1是C

当d=1时,说明2和1是同类,则2就是C

我们只需要判断1C和2C是不是同类即可

当d=2时,说明1吃2,根据题意,C吃A,所以2是A

我们只需要判断1C和2A是不是同类即可

所以对于d = 1,说明1和2必须是同类,也就是find(1) = find(2),抽象化一下就是find(x) == find(y) find(x + n) == find(y + n) find(x + n * 2) == find(y + n * 2),我们只需要找到不等的情况,让sum++即可,对于相等的情况来说,就是正确的,我们就把三种情况分别进行合并

对于d = 2,说明1吃2,根据题中的对应关系,抽象化成find(x) = find(y + n),find(x + n) = find(y + n * 2), find(x + n * 2) = find(y),操作同上

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <stdlib.h>
#include <sstream>
#include <map>
#include <set>
using  namespace std;
#define inf 0x3f3f3f3f
#define MAX 150000 + 5
typedef  long long ll ;

inline int IntRead(){
    char ch = getchar();int s = 0, w = 1;
    while(ch < '0' || ch > '9'){
        if(ch == '-') w = -1;
        ch = getchar();}
    while(ch >= '0' && ch <= '9'){
        s = s * 10 + ch - '0';ch = getchar();}
    return s * w;
}

int n, fa[MAX];
//初始化一定要记得是对n * 3 的数进行初始化
void init(){
    for(int i = 1; i <= n * 3; ++i) fa[i] = i;
}

int find(int x){//找根
    return x == fa[x] ? x : fa[x] = find(fa[x]);
}

void emerge(int x, int y)
{
    fa[find(x)] = find(y);
}

int main()
{
    int d, k ,x, y, sum = 0;
    cin>>n>>k;
    init();
    for(int i = 1; i <= k; ++i){
        cin>>d>>x>>y;
        if(x > n || y > n){
            sum++;
            continue;
        }
        //x 代表x是a,x + n代表x是b, x + 2 * n代表x是c
        if(d == 1){
            if(find(x) == find(y + n) || find(x) == find(y + n * 2)){
                sum++;
                continue;
            }
            emerge(x, y);//合并
            emerge(x + n, y + n);
            emerge(x + n * 2, y + n * 2);
        }
        else if(d == 2){
            if(find(x) == find(y) || find(x) == find(y + n * 2)){
                sum++;
                continue;
            }
            emerge(x, y + n);
            emerge(x + n, y + n * 2);
            emerge(x + n * 2, y);
        }
    }
    cout<<sum<<endl;
    return 0;
}

标签:emerge,ch,题意,查集,同类,include,find,种类
来源: https://www.cnblogs.com/chelsea0901/p/14438116.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有