首页 > 其他分享 >食物链(并查集)

食物链(并查集)

时间:2024-11-13 21:30:57浏览次数:1  
标签:食物链 join int 查集 节点 ans find

题目:https://ac.nowcoder.com/acm/contest/22904/1024

思路:这道题网络上有很多思路,可以开三个并查集,可以使用带权并查集,但是有一个大佬的思路是这样的,将总结点的数量增加到3n个,把整个节点区域分为n,2*n,3*n三个部分,我们可以物种a的一个节点对应物种b的两个节点,如果是同类,我们就把他们通过范围对应起来(如a_n,a_2*n,a_3*n和b_n,b_2*n,b _3*n对应),如果是不是同类,我们让这个节点指向下一个范围的节点(如a_n,a_2*n,a_3*n和b_2*n,b_3*n,b _n对应),如此一来我们只需要判断不同区域范围的节点之间的关系即可

#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 55000;
int a[3*maxn];
void init(int x){
    for(int i=0;i<3*x;i++){
        a[i] = i;
    }
}
int find(int x){
    if(a[x] == x) return x;
    return a[x] = find(a[x]);
}
void join(int x,int y){
    if(find(x) != find(y)) {
        a[find(x)] = find(y);
    }
}
int main(){
    int n,k;
    scanf("%d %d",&n,&k);
    init(n);
    int ans =0;
    while(k--){
        int d,x,y;
        scanf("%d %d %d",&d,&x,&y);
        if((x<1 || x>n || y<1 || y > n) || (d==2 && x==y)) {
            ans++;
            continue;
        }
        if(d==1) {
            if(find(x)==find(y+n) || find(x+n)==find(y)) ans++;
            else {
                join(x,y);
                join(x+n,y+n);
                join(x+2*n,y+2*n);
            }
        }
        else if(d==2){
            if(find(x)==find(y) || find(x+n)==find(y)) ans++;
            else {
                join(x,y+n);
                join(x+n,y+2*n);
                join(x+2*n,y);
            }
        }
    }
    printf("%d",ans);
    return 0;
}

 

标签:食物链,join,int,查集,节点,ans,find
From: https://www.cnblogs.com/mengxiyuan/p/18544869

相关文章

  • 并查集+最小生成树 学习笔记+杂题 2
    图论系列:前言:相关题单:戳我算法讲解:戳我CF1829ETheLakes给定一张\(n*m\)的矩阵,询问正整数四联通块权值和的最大值。并查集维护即可,记录一下集合内的点的权值和。代码:constintM=1005;intT,n,m,ans;inta[M][M],fa[M*M],siz[M*M];intfx[5]={0,1,-1,0,0};intfy[5]......
  • 并查集+最小生成树 学习笔记+杂题 1
    图论系列:前言:相关题单:戳我算法讲解:戳我代码可能过多啊,到时候页面别卡死了,所以就把代码最前面的缺省源删了(反正就是几个头文件/defineintlonglong,自己加一下即可)。并查集记得初始化,最小生成树记得排序。P3367【模板】并查集板子题,给定\(n\)个元素,有2种操作,一种合并,......
  • 并查集 How many tables(hdu 1213) How many answers are wrong(hdu 3038)
    目录前言并查集  并查集的初始化  并查集的合并  并查集合并的优化,路径压缩Howmanytables(hdu1213)  问题描述  输入  输出问题分析代码带权并查集Howmanyanswersarewrong(hdu3038)  问题描述  输入  输出问题分析代码......
  • 并查集+最小生成树 学习笔记
    图论系列:前言:咲いた野の花よああどうか教えておくれ人は何故傷つけあって争うのでしょう相关题单:题单1题单2题单3题单4一.并查集1.基础定义与操作(1)定义并查集是一种用于管理元素所属集合的数据结构,实现为一个森林,其中每棵树表示一个集合,树中的节点表示对应集合中的......
  • 并查集(原理、实现、应用)
    一、原理在一些应用问题中,需要将n个不同的元素划分成一些不相交的集合。开始时,每个元素自成一个单元素集合,然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用到查询某一个元素归属于那个集合的运算。适合于描述这类问题的抽象数据类型称为并查集(union-find......
  • 链式并查集合并(裸板)
    对于操作:将一段元素合并为同类。在合并\([l,r]\)这一段数的时候,其实有很多数本来就在一个并查集里。我们只需要合并若干个还没有合并的并查集,而不需要从\(l\)到\(r\)一个一个合并。因为只要合并了这几个并查集,效果等价于把\([l,r]\)直接合并了。实现方法:每次记录一个......
  • 并查集应用:判圈
    并查集应用:判圈Description第一行输入正整数n,m,q表示一个有n个点m条边的无向图。q表示有q次询问。接下来m行有m条边。每行两个u,v属于[1,n]范围的正整数,表示u,v之间有边。接下来q行,每行两个点u,v,属于[1,n]。如果(u,v)这条边已经存在或者如果加入这条边后会产生新的环,则输出......
  • 并查集
    种类并查集P2024[NOI2001]食物链类似于超级源点,把\(x+n\)丢进集合里,相当于\(x\)对这个集合作了标记,方便维护细节注意\(x\toy\),对于\(y\toz\),会有\(z\tox\)这里会出现自己和自己连边的情况,用\(fa[rt]=0\)的写法需要特判P6008[USACO20JAN]CavePaintingsP主要考察思......
  • 并查集---Linux发行版的数量
    题目描述Linux操作系统有多个发行版,distrowatch.com提供了各个发行版的资料。这些发行版互相存在关联,例如Ubuntu基于Debian开发,而Mint又基于Ubuntu开发,那么我们认为Mint同Debian也存在关联。发行版集是一个或多个相关存在关联的操作系统发行版,集合内不包含没有关联的发行......
  • 计蒜客:修建大桥(并查集/DFS/BFS)
     找到有几张连通图即可解决问题。DFS:1#include<bits/stdc++.h>2usingnamespacestd;3intn,m;4intgraph[1005][1005]={0};5boolvisited[1005]={false};6voiddfs(intp){7if(visited[p]){8return;9}10visited[p]......