摘要: 经过分析,不难知道本题需要维护一个数据结构,使之支持以下操作:1. 合并战舰集合(M i j);2. 查询2艘战舰是否在同一集合/列(C i j);3. 如果在同一集合,求出它们的相对位置。标准的并查集只支持合并和查找操作,并不支持求集合中两元素之间相对距离的操作。所以我们要用扩展并查集。标准并查集中每个节点只有一个域,即用father[i] 表示节点 i 的父亲。本题可以扩展出两个域:用total[i] 表示以 i 为根的集合中的元素个数,它当且仅当i是根时有意义;用front[i] 表示排在 i 前面有多少个点,front[root]=0。若合并操作令 father[a] = b(a 和 阅读全文
posted @ 2013-12-20 16:34 莞中OI 阅读(357) 评论(0) 推荐(0)
摘要: 本题考察扩展并查集。对于这道题,多开辟一个数组来保存天敌关系怎么样?比如读入一个“天敌”关系的时候,就修改“天敌”数组的相应位置,但天敌又有天敌,处理当前天敌关系的时候,对于天敌的天敌是否也需要进行相应修改呢?其实本题有一种非常巧妙的做法,用一个数组father表示合并后的树,用数组rank表示节点和其父节点之间的关系。rank[x] 表示x与father[x]的关系:rank[x] = 0 表示x与 father[x] 是同类rank[x] = 1 表示x吃 father[x](等价于rank[x]=-2)rank[x] = 2 表示 father[x] 吃x(等价于rank[x]=-1)这 阅读全文
posted @ 2013-12-20 16:27 莞中OI 阅读(292) 评论(0) 推荐(0)
摘要: 矩形数目最多是7000,而本题时间限制是2秒,意味着即使用O(n2)级别的算法,也可以不超时。两重循环将矩形两两比较,如果出现重叠,就合并两个矩形,合并操作就用到并查集。关键是如何判断两个矩形重叠。#include typedef int POS;const int maxn = 7000;int n, ans;int pos[maxn][4];// left bottom right top x yint tree[maxn], rank[maxn];bool judge(POS i, POS j){ if (pos[i][0]pos[j][1]) return true; if (pos. 阅读全文
posted @ 2013-12-20 16:07 莞中OI 阅读(179) 评论(0) 推荐(0)