【luogu】p2024 食物链

题目链接w:https://www.luogu.com.cn/problem/P2024

是一个考察并查集的题,代码实现比较简单但思路真的很难想?

看了半天qbxt课件才看懂思路hmmm(菜

大概意思就是建立一个有三层的并查集

如果两个动物是同类就把它们放在同一层

如果x吃y就把y放在x上面的一层 也就是y+n和x在同一个集合

具体来说:

(部分摘自课件)

对每个元素 x 建立 3个元素,xa,xb,xc。

其中xa = x,xb =x+n,xc =x+2*n

如果碰到“1 x y”,说明 x和y 是同类

如果 x 和 y + N 在一个集合里,ans++

如果 x 和 y + 2 * N 在一个集合里,ans++

合并 x 和 y, x + N 和 y + N,x + 2 * N 和 y + 2 * N

如果碰到“2 x y”,说明 x吃y

如果 x和y已经是同类,也就是x 和 y 在一个集合里,ans++

如果 y吃x也就是x 和 y + 2 * N 在一个集合里,ans++

合并x 和 y+N, x+N 和 y+2 * N,x+2 * N 和 y

补充

感觉上面解释的还是不太好懂,个人感觉根据样例手动把这个过程模拟一下会比较好理解hmmm

luogu里第一篇题解写的超级详细可以去看hmm

如果还是不懂就看代码叭

#include<iostream>
#include<cstdio>
using namespace std;
int read(){
    int a = 0,f = 0;char p = getchar();
    while(!isdigit(p)){f|=p=='-';p = getchar();}
    while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p = getchar();}
    return f?-a:a;
}
int n,k;
int fa[300005];//记录祖先的并查集
int find(int x){
    if(fa[x] == x)return x;
    else return fa[x] = find(fa[x]);
}
int main(){
    n = read();k = read();
    int number,X,Y,ans = 0;
    for(int i = 1; i <= 3*n;i ++)fa[i] = i;
    for(int i = 1;i <= k;i ++){
        number = read();
        X = read();Y = read();
        if(X > n||Y > n){
            ans++;continue;
        }
        if(number == 1){
            if(find(X) == find(Y+n)||find(X) == find(Y+2*n))ans++;
            else {
                fa[find(Y)] = find(X);
                fa[find(Y+n)] = find(X+n);
                fa[find(Y+2*n)] = find(X+2*n);
            }
        }
        if(number == 2){
            if(find(X) == find(Y)||find(X) == find(Y+2*n)){ans++;continue;}
            fa[find(Y+n)] = find(X);
            fa[find(Y+2*n)] = find(X+n);
            fa[find(Y)] = find(X+2*n);
        }
    }
    cout<<ans;
}
posted @ 2020-01-30 17:03  蕙心心w  阅读(174)  评论(0编辑  收藏  举报