1 条题解

  • 0
    @ 2025-10-28 16:14:21

    题意理解

    我们有 NN 个节点(棉花糖),初始给定 MM 条边(竹签),要求添加最少的边,使得图满足:

    如果 a<b<ca < b < c,并且有边 (a,b)(a,b)(a,c)(a,c),那么必须有边 (b,c)(b,c)

    换句话说,对于任意节点 aa,与 aa 相连且编号大于 aa 的所有节点之间必须两两相连。

    条件转化

    这个条件等价于:对于任意 aa,由 aa 和所有与 aa 相连且编号大于 aa 的节点构成的子图必须是一个完全图。

    也就是说,如果 aab1,b2,,bkb_1, b_2, \dots, b_k 相连(且 bi>ab_i > a),那么 b1,b2,,bkb_1, b_2, \dots, b_k 之间必须两两相连。

    问题转化

    我们可以这样考虑: 对于每个节点 ii,设 Si=j>i(i,j)ES_i = { j > i \mid (i,j) \in E }(即 ii 的邻居中编号大于 ii 的集合)。 那么 SiS_i 必须是一个完全图,否则需要补边。

    因此,对于每个 ii,如果 Si=k|S_i| = k,那么 SiS_i 中应该有 k(k1)2\frac{k(k-1)}{2} 条边。 如果 SiS_i 中实际存在的边数不足,就需要补足。

    高效计算方法

    直接枚举每个 ii 并检查 SiS_i 中的边数会超时(O(N2)O(N^2) 不可行)。

    我们可以这样优化:

    按节点编号从大到小处理(从 NN11)。

    维护每个节点的“右邻居列表”,并按编号排序。

    对于节点 ii,它的 SiS_i 就是它的右邻居集合。

    要检查 SiS_i 中哪些边已经存在,我们可以利用之前处理过的信息: 对于 u,vSiu, v \in S_iu<vu < v),边 (u,v)(u,v) 存在当且仅当 uuvv 的邻居(因为 u<vu < v,所以 uuvv 的右邻居列表中)。

    具体算法:

    读入边,用邻接表存储(只存编号大的邻居到编号小的邻居?不,我们存双向,但处理时只关心右邻居)。

    对每个节点的右邻居列表排序。

    NN11 处理每个节点 ii

    RR = ii 的右邻居列表。

    需要的边数 = R×(R1)/2|R| \times (|R|-1)/2

    实际存在的边数:对 RR 中每对 (x,y)(x,y)x<yx<y),检查 xx 是否在 yy 的右邻居列表中(可以用二分查找,因为列表有序)。

    缺失的边数 = 需要的边数 - 实际存在的边数。

    累加所有缺失的边数,加上初始的 MM 条边,就是答案。

    但这样检查每对 (x,y)(x,y) 还是可能 O(k2)O(k^2),最坏 O(N2)O(N^2)

    进一步优化

    我们可以用更高效的方法计算 SiS_i 中已经存在的边数:

    对于节点 ii,它的右邻居集合 RR 已经排序。 对于每个 uRu \in Ruu 的右邻居集合 RuR_uRR 的交集大小,就是 uuSiS_i 中已经连接的邻居数(且编号大于 uu)。 实现细节 我们可以用 vector adj[N+1] 存储邻接表,并且每个节点的邻居列表排序。

    然后对每个 ii

    R=adj[i]R = adj[i] 中大于 ii 的部分(其实存储时可以只存大于 ii 的邻居,但输入边是双向的,我们存储时只存 a<ba<b 的边?不,我们存储双向,但处理时过滤)。

    实际计算时,我们只关心 ii 的邻居中编号大于 ii 的,所以可以预先对每个节点 ii 的邻居排序,然后取后缀。

    更简单的方法: 我们只考虑 a<ba < b 的边,然后对每个 aa,它的右邻居列表自然就是所有 bb

    这样我们只需要:

    读入边 (a,b)(a,b)a<ba<b,加入 adj[a]adj[a]

    对每个 adj[a]adj[a] 排序。

    对每个 aa,计算需要的完全边数,减去已有的边数。

    复杂度分析

    排序所有邻居列表:O(dilogdi)O(\sum d_i \log d_i)

    主循环中,对每个节点 ii,检查所有右邻居的邻居列表交集: 总复杂度 O(iuRi(Ri+adj[u]))O(\sum_i \sum_{u \in R_i} (|R_i| + |adj[u]|))。 最坏情况下是 O(N3)O(N^3),但实际数据中很难达到,因为度数和是 O(M)O(M)

    对于 N,M105N, M \le 10^5,这个算法在随机数据上可以接受,但最坏情况可能超时。

    • 1

    信息

    ID
    4514
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者