【POJ 1182 食物链】并查集

简介: 此题按照《挑战程序设计竞赛(第2版)》P89的解法,不容易想到,但想清楚了代码还是比较直观的。 并查集模板(包含了记录高度的rank数组和查询时状态压缩) 1 const int MAX_N=50002*3; 2 int par[MAX_N]; 3 int rank[MAX_N]...

此题按照《挑战程序设计竞赛(第2版)》P89的解法,不容易想到,但想清楚了代码还是比较直观的。

并查集模板(包含了记录高度的rank数组和查询时状态压缩)

 1 const int MAX_N=50002*3;
 2 int par[MAX_N];
 3 int rank[MAX_N];
 4 //初始化,根为自身,高度为0
 5 void init(int scab)
 6 {
 7     for(int i=1;i<=scab;i++)
 8     {
 9         par[i]=i;
10         rank[i]=0;
11     }
12 }
13 //查找,途径的所有结点都直接连到根上
14 int find(int x)
15 {
16     if(par[x]==x) return x;
17     return par[x]=find(par[x]);
18 }
19 //合并,把短链连接到长链上,保持结点高度的相对关系
20 int unite(int x,int y)
21 {
22     x=find(x);
23     y=find(y);
24     if(x==y) return 0;
25     if(rank[x]<rank[y]) {par[x]=y; return 1;}
26     par[y]=x;
27     if(rank[x]==rank[y]) rank[x]++;
28     return 1;
29 }
并查集实现

并查集是用于维护“属于同一集合”的数据结构,然而这道题的“属于同一集合”并不指“是同类”,而是指“这几个情况若发生必然同时发生”。

我们从理解题意开始:

有N只动物,分别编号为1,2,...,N。所有动物属于A,B,C类中的一种,类之间有天然的A吃B,B吃C,C吃A的关系。

按如下两种格式顺序给出共K条信息(只表达了相对关系):

1 x y: x,y是同类

2 x y: x吃y

每条信息若不符合常理(编号大于N,或自己吃自己)或与已有信息矛盾,则为错误。

问这K条信息有几条错误?

由于A,B,C之间的吃与被吃关系构成一个循环,所以三类的等级关系根本上也是相对的,那么每条信息都可以翻译成三种可能的实际情况。同时维护这三种可能

,就需要为每个动物x分配三个数组元素,分别表示x是A,x是B,x是C这三个事件。

同属一个集合的事件意味着“若发生必然同时发生”。

并查集需要用一个数组存储每个元素“属于哪一集合”,那么可以开一个长度为N*3的数组,用x,x+N,x+N*2分别表示x是A,x是B,x是C。

表示x与y是同类,需要维护这三种可能

unite(x,y);        //x,y都是A
unite(x+n,y+n);     //x,y都是B
unite(x+2*n,y+2*n); //x,y都是C

表示x吃y,需要维护这三种可能

unite(x,y+n);    //x是A,y是B
unite(x+n,y+2*n);  //x是B,y是C
unite(x+2*n,y);  //x是C,y是A

想清楚了道理,代码就比较好理解了。注意由于从始至终只知道相对关系,同时维护了三种可能,所以判断矛盾的时候任选一种判断就可以了。

 1 int main()
 2 {
 3     freopen("e.txt","r",stdin);
 4     scanf("%d%d",&n,&k);
 5     ans=0;
 6     init(n*3);
 7     while(k--)
 8     {
 9         scanf("%d%d%d",&d,&x,&y);
10         if(x>n||y>n)
11         {
12             ans++;
13             continue;
14         }
15         if(d==1)
16         {//若想成为同类,就不可能有x吃y或y吃x的关系
17             if(find(x)==find(y+n)||find(y)==find(x+n))
18                 ans++;
19             else
20             {
21                 unite(x,y);
22                 unite(x+n,y+n);
23                 unite(x+2*n,y+2*n);
24             }
25         }
26         else if(d==2)
27         {
28             if(x==y) ans++;
29             //若想x吃y,则x,y不可能是同类,也不可能y吃x
30             else if(find(x)==find(y)||find(y)==find(x+n))
31                 ans++;
32             else
33             {
34                 unite(x,y+n);
35                 unite(x+n,y+2*n);
36                 unite(x+2*n,y);
37             }
38         }
39     }
40     printf("%d\n",ans);
41     return 0;
42 }

OJ运行结果如下:

这道题使我对并查集有了新的认识,想清楚“同属一个集合”代表什么很重要,不一定就是题目限定的“属于同一种”。

分析问题的难度有时会大于编程的难度,如果说代码能力可以通过刷题习得,那么分析问题的能力真的需要足够的知识储备和一些“创造性思维”了。

目录
相关文章
|
9月前
|
消息中间件 存储 网络协议
从零开始掌握进程间通信:管道、信号、消息队列、共享内存大揭秘
本文详细介绍了进程间通信(IPC)的六种主要方式:管道、信号、消息队列、共享内存、信号量和套接字。每种方式都有其特点和适用场景,如管道适用于父子进程间的通信,消息队列能传递结构化数据,共享内存提供高速数据交换,信号量用于同步控制,套接字支持跨网络通信。通过对比和分析,帮助读者理解并选择合适的IPC机制,以提高系统性能和可靠性。
1153 14
|
9月前
|
存储 传感器 人工智能
《软硬协同优化,解锁鸿蒙系统AI应用性能新高度》
在数字化时代,鸿蒙系统与AI的融合备受关注。鸿蒙凭借微内核架构和分布式特性,支持语音助手、图像识别等AI应用,提升用户体验。为应对复杂AI需求,软硬件协同优化成为关键:软件方面通过算法、资源管理和框架优化挖掘潜力;硬件方面则通过芯片适配、传感器和存储优化提供动力。两者协同实现资源共享、任务调度和数据处理的突破,大幅提升性能,推动智能化体验迈向新高度。
353 9
|
机器学习/深度学习 算法
爬山算法的详细介绍
爬山算法的详细介绍
|
12月前
|
安全 Linux 开发者
|
11月前
|
机器学习/深度学习 自然语言处理 并行计算
DeepSpeed分布式训练框架深度学习指南
【11月更文挑战第6天】随着深度学习模型规模的日益增大,训练这些模型所需的计算资源和时间成本也随之增加。传统的单机训练方式已难以应对大规模模型的训练需求。
1279 3
|
人工智能 数据可视化 Python
【2024美赛】C题 Problem C: Momentum in Tennis网球运动中的势头26页完整论文
本文是关于2024美国大学生数学建模竞赛C题"网球运动中的势头"的完整论文,由一位自称对网球规则和比赛数据非常熟悉的计算机博士撰写,提供了问题分析、数学模型、实现代码和26页的完整论文。
1145 2
【2024美赛】C题 Problem C: Momentum in Tennis网球运动中的势头26页完整论文
|
机器学习/深度学习 计算机视觉
【YOLOv8改进 - 注意力机制】ECA(Efficient Channel Attention):高效通道注意 模块,降低参数量
YOLO目标检测专栏聚焦模型创新与实战,介绍了一种高效通道注意力模块(ECA),用于提升CNN性能。ECA仅用少量参数实现显著性能增益,避免了维度缩减,通过1D卷积进行局部跨通道交互。代码实现展示了一个ECA层的结构,该层在多种任务中展现优秀泛化能力,同时保持低模型复杂性。论文和代码链接分别指向arXiv与GitHub。更多详情可查阅CSDN博主shangyanaf的相关文章。
|
计算机视觉 网络架构
【YOLOv8改进】MSBlock : 分层特征融合策略 (论文笔记+引入代码)
YOLO-MS是一个创新的实时目标检测器,通过多尺度构建块(MS-Block)和异构Kernel选择(HKS)协议提升多尺度特征表示能力。它在不依赖预训练权重和大型数据集的情况下,在MS COCO上超越了YOLO-v7和RTMDet,例如YOLO-MS XS版本(4.5M参数,8.7G FLOPs)达到了43%+的AP,比RTMDet高2%+。MS-Block利用分层特征融合和不同大小的卷积,而HKS协议根据网络深度调整Kernel大小,优化多尺度语义信息捕获。此外,YOLO-MS的模块化设计允许其作为即插即用的组件集成到其他YOLO模型中,提升它们的检测性能。
|
缓存 分布式计算 资源调度
MapReduce入门(一篇就够了)
MapReduce入门(一篇就够了)
9069 0
MapReduce入门(一篇就够了)
|
机器学习/深度学习 存储 C语言
NumPy源码解析:实现原理探究
【4月更文挑战第17天】本文深入解析NumPy源码,探讨其高效性能背后的实现原理。核心是多维数组`ndarray`,基于同质数据、连续内存分配和形状步幅概念。NumPy利用C语言实现数组管理,通过广播机制允许不同形状数组运算,并借助底层线性代数库实现向量化操作。理解这些机制有助于优化科学计算并应用于其他项目。