食物链【并查集+不知道1是A,B,C哪一类的?用x,x+n,x+n+n分别表示A,B,C中有个1】【并查集中用距离表示关系】【压缩路径】
创始人
2024-03-01 23:13:49
0

欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录)
文章字体风格:
红色文字表示:重难点
蓝色文字表示:思路以及想法
 
如果大家觉得有帮助的话,感谢大家帮忙点赞!收藏!转发!

食物链

        • 法一: x,x+n,x+n+n
        • 法二:将有关系的都存储在一个部落,用到根节点的距离表示关系
          • 注意:
          • 1. 原始距离都为0
          • 2. find具有路径压缩的作用:子节点到根节点的距离 = 子节点到父节点的距离 + 父节点到根节点的距离
          • 3. A吃B则 A的父节点 等于B的父节点
        • 1. 具体步骤如图:
        • 2. 为什么有路径压缩
        • 3. 怎么处理两个根节点的距离(设数法);距离可能是负数

法一: x,x+n,x+n+n

在这里插入图片描述

思路:

  1. 因为有三种物种,A吃B,B吃C,C吃A
  2. 如果我们用一个数组存储,那么比如1吃2,那么我们让2的角标处的值标记成1,如果3吃2,那怎么标记?一个数组指定标记不过来。
  3. 那么我们想用三个数组存储,其实也存储不过来,因为角标就那么几个,
  4. 最好的方法就是,用x,x+n,x+n+n来表示
    比如1吃2,那么就可能有三种情况,
    A类中的1吃B类的2 : fa[1] = fa[2+n+n]
    B类中的1吃C类的2 : fa[1+n] = fa[2]
    C类中的1中A类的2 : fa[1+n+n] = fa[2+n];
    这样的话,就会有3*n个角标,就可以充分表达
    A中的1吃B中的2(B中的2用2+n表示)
    这样的话就不会出现数字冲突
/**/#include 
using namespace std;
int fa[200000];
int n,m,k,x,y,ans;
int get(int x)
{if(x==fa[x]) return x;return fa[x]=get(fa[x]);
}
void merge(int x,int y)
{fa[get(x)]=get(y);
}
int main()
{cin>>n>>m;for(int i=1;i<=3*n;i++) fa[i]=i;for(int i=1;i<=m;i++){scanf("%d%d%d",&k,&x,&y);if(x>n || y>n) ans++;else if(k==1){if(get(x)==get(y+n) || get(x)==get(y+n+n)) //如果x,y是同类,但是x是y的捕食中的动物,或者x是y天敌中的动物,那么错误.ans++;else{merge(x,y);merge(x+n,y+n);merge(x+n+n,y+n+n);}}else{if(x==y || get(x)==get(y) || get(x)==get(y+n)) //x就是y,或者他们是同类,再或者是y的同类中有xans++;//都是假话else{merge(x,y+n+n);//y的捕食域加入xmerge(x+n,y);//x的天敌域加入ymerge(x+n+n,y+n);//x的捕食域是y的同类域.}}}cout<

法二:将有关系的都存储在一个部落,用到根节点的距离表示关系

注意:
1. 原始距离都为0
2. find具有路径压缩的作用:子节点到根节点的距离 = 子节点到父节点的距离 + 父节点到根节点的距离
3. A吃B则 A的父节点 等于B的父节点

1. 具体步骤如图:

在这里插入图片描述

2. 为什么有路径压缩

在这里插入图片描述

3. 怎么处理两个根节点的距离(设数法);距离可能是负数

在这里插入图片描述

具体过程如下:

#include using namespace std;const int N = 50010;int n, m;
int p[N], d[N];int find(int x)
{if (p[x] != x){int t = find(p[x]);d[x] += d[p[x]];p[x] = t;}return p[x];
}int main()
{scanf("%d%d", &n, &m);for (int i = 1; i <= n; i ++ ) p[i] = i;int res = 0;while (m -- ){int t, x, y;scanf("%d%d%d", &t, &x, &y);if (x > n || y > n) res ++ ;else{int px = find(x), py = find(y);if (t == 1){if (px == py && (d[x] - d[y]) % 3) res ++ ;else if (px != py){p[px] = py;d[px] = d[y] - d[x];}}else{if (px == py && (d[x] - d[y] - 1) % 3) res ++ ;else if (px != py){p[px] = py;d[px] = d[y] + 1 - d[x];}}}}printf("%d\n", res);return 0;
}

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...