当前位置: 首页 > news >正文

ch09 题目参考思路

ch09 - 拓扑排序与基环树

SAT 问题

  • 知识点:基环森林
  • 思路:
    • 题意解释:题目会输入 n 对二元关系,每对二元关系要保证对应位置填数不同(只能填 0 或 1)。如样例 1 输入 2,3,4,1,对应四对二元关系,分别是 (1, 2),(2, 3),(3, 4),(4, 1),其中 (1,2) 表示 1,2 位置所填的数不能相同(比如 1 填 T,那么 2 只能填 F,或者 1 填 F,那 2 只能填 T),其他二元关系也是如此。
    • 对于每一对二元关系,我们可以理解为一条无向边,比如二元关系 (1, 2),可以认为节点 1 和节点 2 之间连了一条边,以此类推,我们能得到下图所示的基环树(左 1)。
      SAT问题
    • 建图之后,问题可以变成在图上染色的过程,当某个点确定之后,相邻节点的颜色也确定了,依次类推,整张图的染色也确定了,由于初始节点有两种染色方案,因此总的方案数为 2。
      • 情形 1:图上环的长度为奇数(有奇数个节点),那么不存在可行的染色方案。
      • 情形 2:图上的一个连通块中不止有环,还有连接其他节点,这些节点不会影响染色过程,可以忽略。
      • 综上所述,如果图中不存在奇数长度的环,且忽略所有不在环上的节点后,图上只存在若干长度为偶数的环,记环的个数为 k k k,并且每个长度为偶数的环的染色方案为 2,根据乘法原理,总的方案数为 2 k 2^k 2k(可以通过样例 2 建图理解)。
    • 代码思路:先根据拓扑排序的思路,将所有不在环上的节点排除,再统计每个环上节点的个数,并统计环的个数 k k k。如果存在奇数长度的环,答案为 0,否则答案为 2 k 2^k 2k

收敛的数组

  • 知识点:基环树、并查集
  • 思路:
    • 对于每一轮赋值操作, i = a i i = a_i i=ai,可以认为数 i i i 变成了 a i a_i ai,因此可以看成是节点 i i i 到节点 a i a_i ai 有一条出边,表示从节点 i i i 能一步到达节点 a i a_i ai。更具体地,每个数 i i i 都看成一个节点,编号从 1 ∼ n 1 \sim n 1n,对于输入的每个 a i a_i ai,可以认为从节点 i i i 到节点 a i a_i ai 有一条出边,形成一个基环内向森林(可能有多个基环内向树)。
    • 题目的问题在图上可以转换为,修改最少的边使得可以找到一个节点 x,所有节点(包括 x 本身)能经过 n - 1 条边到达 x。
    • 对于一棵基环内向树而言
      • 选择的节点 x 必须在环上,因为如果选择的点 x 在环外,那么环上的点无论如何都无法到达 x,不符合要求。
      • 环上的节点只能有一个(自环),因为如果环上的节点大于等于 2,随意选择任何一个节点作为 x,那么每个节点到达 x 的距离都是不一样的,因此不存在任何距离 k(题目中是 n - 1),使得每个节点到 x 的距离都是 k。
      • 综上所述,对于每一棵基环内向树而言,我们需要找到一个终点,让它变成自环,这样才能使得每个点到终点的距离为 n - 1。
    • 统计需要修改的边数
      • 记该基环内向森林中有 cnt 棵基环内向树。
      • 如果一棵基环内向树中本身就有一个自环,那么可以把它作为终点 x,所有其他树需要连一条边到这个终点上(或者该树的其他点上,效果都一样),需要的边数取决于有多少棵其他的基环内向树,即 cnt - 1
        • 可以通过并查集统计基环内向树的数量(同一棵树上的节点可以认为在同一个集合中,最后统计有多少个集合)
      • 如果不存在任何一棵基环内向树中有自环,则需要额外修改一条边,将某个节点改成自环。总共需要修改 cnt 条边。

Piggy banks

  • 知识点:基环树、并查集
  • 思路:
    • 题意解释:有 n 个存钱罐和 n 把钥匙,要想获得第 i 个存钱罐中的钱,有两种方式,一种是将存钱罐打碎,另一种是通过它对应的第 i 把钥匙开启。
      • 每个存钱罐中除了有钱之外,可能还放有其他存钱罐的钥匙。问最少需要打碎多少存钱罐,将里面的所有钱全部拿出来。
    • 将每个罐子看成一个节点,如果编号为 x 的罐子中有着编号为 i 罐子的钥匙,那么可以认为,有一条从节点 x 到节点 i 的有向边,表示通过节点 x 能打开 i 号罐子,从而形成基环外向森林。例如,对于样例而言,如下图所示,其中圆形表示罐子,三角形表示罐子钥匙。
      P3420 [POI2005]SKA-Piggy Banks
    • 对于一棵基环外向树而言,只需要打碎其中一个在环上的罐子,就能访问到所有其他罐子了。因此问题就变成计算有多少棵基环外向树的问题了(每一棵基环外向树都需要打碎一个罐子)
      • 同样地,可以通过并查集统计有多少棵基环外向树(每一个基环外向树是一个集合)

相关文章:

  • LVDS系列11:Xilinx Ultrascale系可编程输入延迟(一)
  • 第8章-4 查询性能优化2
  • U9C-SQL-调出单视图
  • 想更好应对突发网络与业务问题?需要一款“全流量”工具
  • SQL注入的绕过方式
  • MySQL基础关键_013_常用 DBA 命令
  • 三款实用电脑工具
  • 机器学习之静态推理与动态推理:选择适合你的策略
  • ACTF2025 - Web writeup
  • Femap许可使用数据分析
  • uniapp自定义导航栏搭配插槽
  • 学习threejs,使用Physijs物理引擎
  • 【PostgreSQL数据分析实战:从数据清洗到可视化全流程】电商数据分析案例-9.3 商品销售预测模型
  • C++中volatile关键字详解
  • Ubuntu通过源码编译方式单独安装python3.12
  • 高并发内存池(二):项目的整体框架以及Thread_Cache的结构设计
  • Starrocks 的 ShortCircuit短路径
  • 橡胶制品行业质检管理的痛点 质检LIMS如何重构橡胶制品质检价值链
  • WebRTC 源码原生端Demo入门-1
  • 02_线性模型(回归线性模型)
  • 云南省安委会办公室:大理州安全生产形势比较严峻,事故总量一直居高不下
  • 本周看啥|喜欢二次元的观众,去电影院吧
  • 上海:企业招用高校毕业生可享受1500元/人一次性扩岗补助
  • 九家企业与上海静安集中签约,投资额超10亿元
  • 化学家、台湾地区“中研院”原学术副院长陈长谦逝世
  • 从黄土高原到黄浦江畔,澄城樱桃品牌推介会明日在上海举办