1 条题解
-
0
题解:Access Levels 问题重述 有 个开发者和 份文档,用一个 的 0‑1 矩阵 表示访问需求: 表示开发者 必须 能访问文档 , 表示开发者 必须不能 访问文档 。
我们可以进行以下操作:
选择访问组的数量 ;
为每份文档指定一个访问组()和一个所需访问级别();
为每个开发者指定 个访问级别(每个组一个,)。
开发者 能访问文档 当且仅当:在文档 所在的组 中,开发者的级别 文档的所需级别。
目标:用最少的组 实现给定的访问需求表,并输出任意一种合法的分配。
核心观察 同一组内的文档必须满足“可比性”
假设两份文档 和 被分到同一个组,且它们的所需级别不同。不妨设文档 的所需级别 的所需级别。那么任何能访问 的开发者(其级别 的级别)必然也能访问 (因为级别 的级别 的级别)。因此对于所有开发者 ,必须有 ai,x≥ai,y.a i,x≥a i,y . 即文档 对应的列向量(长度为 )逐元素不小于文档 的列向量。记作 。
反之,如果两个文档的列向量不可比(存在 使 ,且存在 使 ),则它们不可能放在同一个组中,否则会出现循环要求( 与 不能同时成立)。
因此,同一组内的文档对应的列向量必须构成一个全序(按 关系)。列向量完全相同的文档自然可以放在同一组,且可以赋予相同的所需级别。
转化为最小链覆盖问题 将每份文档视为一个节点,节点 的权值为其列向量 。定义有向边 当且仅当 且 (逐元素)。这是一个偏序关系,构成的图是一个 DAG(相等情况已合并)。
我们需要将节点划分成最少的链(每条链是一个全序子集),每条链对应一个访问组。这就是经典的最小链覆盖问题。
对于 DAG,最小链覆盖 节点数 最大匹配(拆点二分图上的匹配)。具体地:
将每个节点 拆成左部 和右部 ;
若原图有边 ,则在二分图中连接 与 ;
求最大匹配,匹配边数 ,则最小链覆盖 ,其中 是节点数。
处理相同列向量 如果两个文档的列向量完全相同,则它们之间互相有边( 且 ),从而形成环,不能直接使用 DAG 上的链覆盖。但我们可以将它们合并为一个节点,因为:
它们必须放在同一个组中(否则若分在不同组,无法满足可比性?实际上可以分在不同组,但为了最小化组数,合并后更优;而且合并不会破坏可行性,因为我们可以给它们分配相同的所需级别)。
合并后,图变为 DAG。
具体做法:将所有文档的列向量收集起来,排序去重,得到 个不同的向量。每个原始文档对应其中一个类别。
算法步骤
-
输入与压缩 读入 和 行二进制字符串。将每份文档的列(长度为 )存储为字符串 b[j]。 去重:将 b 排序并 unique,得到 nw 数组(大小为 ),以及每个原始文档所属的类别编号 num[j]。
-
建图 对 ,若 且 nw[i] 的每一位 nw[j] 的对应位,则在二分图左部 与右部 之间连边。 注意:由于已去重, 时不会出现双向边,图是 DAG。
-
求最大匹配 在二分图上运行匈牙利算法(或最大流)。得到匹配数组 mt:mt[r] = l 表示右部节点 匹配左部节点 。
-
重建路径 初始化 nxt[l] = -1,st[l] = true(表示左部节点是否为路径起点)。
遍历所有匹配:若 mt[r] = l,则令 nxt[l] = r,且 st[r] = false(右部节点 有前驱,不是起点)。
此时所有左部节点中 st[l] == true 的就是各条路径的起点。
- 分配组号和所需级别 对每条路径从起点开始沿着 nxt 走,依次给路径上的节点分配:
组号 gr[v] = t( 从 开始递增);
所需级别 req[v] = pos,其中 pos 从 开始递增(保证严格递增,且最小为 ,方便后面构造开发者的级别)。
路径上的节点顺序就是所需级别递减的顺序(首节点所需级别最高)。
- 输出文档的分配 对于每个原始文档 (‑based),其类别为 num[j],输出:
组号 gr[num[j]] + 1;
所需级别 req[num[j]]。
- 构造开发者的访问级别 对于每个开发者 (‑based),初始化一个长度为 的数组 l 全为 。 遍历所有不同的文档类别 (),如果 nw[v][i] == '1'(即开发者 需要访问这类文档),则更新 l[gr[v]]=max(l[gr[v]],req[v]). 最后输出 l[0..k-1]。
正确性说明:在一条链(一个组)中,由于所需级别严格递增且列向量单调递减,每个开发者的需求模式必然是一段连续的 1 后面全是 0(因为向量逐元素非增)。因此,他需要的文档恰好是链中所需级别最高的若干文档。设他需要的最后一个文档的所需级别为 ,则 时:
对所有需要的文档,级别 所需级别;
对所有不需要的文档,所需级别 ,故无访问。
将 设为所有需要文档的 req 最大值,正好满足要求。初始值 保证了当开发者不需要任何文档时,级别 小于所有所需级别()。
复杂度分析 去重:。
建图:,,最坏 ,但实际常数小且数据随机时可接受。
匈牙利算法:,,仍可运行。
总复杂度:,符合题目限制。
-
- 1
信息
- ID
- 6554
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 7
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者