增量最大聚簇规模:因子对边事件流上的流式并查集
Incremental Largest Cluster Size: Streaming Union-Find on a Factor-Pair Edge Tape
开始编码实现 solution(n_nodes: int, edges: list[list[int]]) -> list[int]。在顶点 0..n_nodes - 1 上按给定顺序处理 M 条无向边。每处理一条边后,把当前图上最大连通分量的规模追加到输出。返回长度为 M 的列表。
例
solution(5, [[0, 1], [2, 3], [1, 2]]) 返回 [2, 2, 4]。边 [0, 1] 把孤点 {0} 与 {1} 合成大小 2 的分量,把当前最大值从 1 抬到 2。边 [2, 3] 合出另一独立的大小 2 分量;最大值保持 2。边 [1, 2] 把 {0, 1} 与 {2, 3} 合成大小 4 的分量,最大值跳到 4。solution(5, [[0, 1]]) 返回 [2]。solution(0, []) 与 solution(1, []) 与 solution(5, []) 都返回 []。solution(3, [[0, 1], [0, 1], [1, 2]]) 返回 [2, 2, 3] —— 重复边对全局序列是空操作。
参考解一遍走完边流,把每对端点送进带路径压缩与按秩合并的并查集,并仅在成功合并产生严格大于当前 current_lcc 的新分量时更新这个跨迭代计数器。每条边后扫 max(size[r] for r in roots) 是 O(M * N),会在 M 与 n_nodes 上限处吃光预算。每个输出条目等于对应边处理之后的 current_lcc。
契约细节:"最大"取的是当前运行图上的全局最大分量大小。孤点本身就是大小 1 的分量,所以任何成功合并发生之前 current_lcc 就是 1;首次在两个原本孤立点之间成功合并把它抬到 2。已合并分量内部的重复边或冗余边对 current_lcc 没有影响,会在输出里产生一条重复值。没有异常路径——任何 2 元素边只要 u != v 且下标在合法区间内都被接受;输入域之外的取值不在契约范围之内。空输入(n_nodes == 0 或 M == 0)短路到 [],不再做任何后续工作。
实现细节由 stubs/stub.py 提供。
实践背景
流式聚类监控盯着当日的因子对相似度事件流。每条事件携带两个因子标识,它们的逐对相似度刚刚穿越桌面设定的阈值,作为一条新边落到无向图上。风险线希望每处理完一条新事件就拿到运行图上最大连通因子聚簇的大小作为单数集中度风险标量——当某个聚簇吞下超过策略上限比例的因子,风险线就停止往这个 bucket 加新因子并回头再平衡下游敞口。增量输出(每条事件一个数)让下游告警层在阈值被破时即时触发,无需等到收盘。这条算法形态——一遍单趟并查集加跨迭代的 current_lcc——正是这类流式风险表盘需要的形态。
约束条件
- 0 <= n_nodes <= 5000,0 <= M <= 5000,M 是 edges 列表的长度
- 每条边是 2 元素列表 [u, v],满足 u != v 与 0 <= u, v < n_nodes
- 重复边与平行边被允许,且当 u 与 v 已属同一连通分量时视为空操作
- n_nodes == 0 时对任何 edges 都返回 [](无节点可合并);M == 0 时对任何 n_nodes 都返回 []
- 输出永远是长度恰为 M 的整数列表,使用精确相等与顺序比对
样例
Case 1 · statement-example: 5 nodes, three edges, LCC series 2,2,4
输入: [5,[[0,1],[2,3],[1,2]]]
期望: [2,2,4]
边 [0,1] 合出大小 2 的块,边 [2,3] 合出独立大小 2 的块(最大仍为 2),边 [1,2] 把两块并到一起得到大小 4。
Case 2 · visible: single-edge bump from 1 to 2
输入: [5,[[0,1]]]
期望: [2]
首条边把孤立 {0} 与 {1} 合成大小 2,最大值从 1 抬到 2。
Case 3 · visible: empty edges list returns []
输入: [5,[]]
期望: []
M = 0,无论 n_nodes 取值都返回空列表。
Case 4 · visible: n_nodes = 0 returns []
输入: [0,[]]
期望: []
无节点可合并,输出长度为 0。
Case 5 · visible: duplicate edge is a no-op
输入: [3,[[0,1],[0,1],[1,2]]]
期望: [2,2,3]
第二条 [0,1] 与已合并对重复,不影响最大值;第三条 [1,2] 把链合到大小 3。
Case 6 · boundary: n_nodes = 1 with empty edges
输入: [1,[]]
期望: []
单节点本身是大小 1 的分量,但 M = 0 输出为 []。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · statement-example: 5 nodes, three edges, LCC series 2,2,4
输入: [5,[[0,1],[2,3],[1,2]]]
期望: [2,2,4]
边 [0,1] 合出大小 2 的块,边 [2,3] 合出独立大小 2 的块(最大仍为 2),边 [1,2] 把两块并到一起得到大小 4。
Case 2 · visible: single-edge bump from 1 to 2
输入: [5,[[0,1]]]
期望: [2]
首条边把孤立 {0} 与 {1} 合成大小 2,最大值从 1 抬到 2。
Case 3 · visible: empty edges list returns []
输入: [5,[]]
期望: []
M = 0,无论 n_nodes 取值都返回空列表。
Case 4 · visible: n_nodes = 0 returns []
输入: [0,[]]
期望: []
无节点可合并,输出长度为 0。
Case 5 · visible: duplicate edge is a no-op
输入: [3,[[0,1],[0,1],[1,2]]]
期望: [2,2,3]
第二条 [0,1] 与已合并对重复,不影响最大值;第三条 [1,2] 把链合到大小 3。
Case 6 · boundary: n_nodes = 1 with empty edges
输入: [1,[]]
期望: []
单节点本身是大小 1 的分量,但 M = 0 输出为 []。