OI Wiki 弦图:如何判定弦图并利用其性质求解问题

发布时间:2026/9/15 18:53:26

OI Wiki 弦图:如何判定弦图并利用其性质求解问题 OI Wiki 弦图如何判定弦图并利用其性质求解问题【免费下载链接】OI-wiki:star2: Wiki of OI / ICPC for everyone. 某大型游戏线上攻略内含炫酷算术魔法项目地址: https://gitcode.com/GitHub_Trending/oi/OI-wikiOI Wiki 图论部分的 弦图 文档回答了一个具体任务给定一个无向图先判断它是否为弦图如果是则借助完美消除序列在 O(nm) 时间复杂度内求出极大团、色数/团数、最大独立集和最小团覆盖。这些内容之所以有用是因为很多在一般图上 NP-Hard 的问题在弦图上都有线性时间复杂度的算法所以先判定、再利用性质是一条可落地的解题路径。前提条件输入是无向图记点数为 n、边数为 m。下文代码均为该文档给出的 C 参考实现片段依赖G邻接表、p序号数组、rnk秩数组等原实现中的全局变量用于展示算法核心逻辑不是可直接编译运行的完整程序。判定弦图需要掌握的三个概念判定算法建立在这三个定义之上单纯点设 N(x) 为与点 x 相邻的点集若 {x}N(x) 的导出子图为一个团则 x 为单纯点。完美消除序列v₁, v₂, …, vₙ 是 1…n 的一个排列满足每个 vᵢ 在 {vᵢ, vᵢ₊₁, …, vₙ} 的导出子图中为单纯点。核心判据Lemma 8一个无向图是弦图当且仅当它存在完美消除序列。判定任务由此转化为两件事求出候选序列MCS 算法再验证该序列是否为完美消除序列。基线方法反复删除单纯点文档先给出朴素算法适合先理解判定原理每次找到一个单纯点 v将其加入完美消除序列将点 v 与其相邻的边从图上删除重复上述过程若所有点都被删除则原图是弦图且已求得一个完美消除序列若图上不存在单纯点则原图不是弦图。时间复杂度 O(n⁴)只适合作为理解基线或极小规模图上的做法不作为主路径。主路径用最大势算法MCS在 O(nm) 内求序列最大势算法Maximum Cardinality Search是文档给出的主路径逆序给结点编号即按从 n 到 1 的顺序给点标号设 labelₓ 表示第 x 个点与多少个已经标号的点相邻每次选择 label 值最大的未标号结点进行标号用链表维护对于每个 i满足 labelₓi 的 x。由于每条边对 Σ labelᵢ 的贡献最多是 2时间复杂度 O(nm)。文档中 MCS 的核心循环如下原实现片段h/deg/nxt/lst为按 label 值分桶的链表结构tf记录已标号点cur为当前标号位置while (cur) { p[cur] h[nww]; rnk[p[cur]] cur; h[nww] nxt[h[nww]]; lst[h[nww]] 0; lst[p[cur]] nxt[p[cur]] 0; tf[p[cur]] true; for (vectorint::iterator it G[p[cur]].begin(); it ! G[p[cur]].end(); it) if (!tf[*it]) { if (h[deg[*it]] *it) h[deg[*it]] nxt[*it]; nxt[lst[*it]] nxt[*it]; lst[nxt[*it]] lst[*it]; lst[*it] nxt[*it] 0; deg[*it]; nxt[*it] h[deg[*it]]; lst[h[deg[*it]]] *it; h[deg[*it]] *it; } cur--; if (h[nww 1]) nww; while (nww !h[nww]) nww--; }注意原图可能不是弦图此时 MCS 求出的序列一定不是完美消除序列所以不能到此为止必须接着验证序列本身。验证求出的序列是不是完美消除序列朴素算法根据定义依次检查序列上每个 vᵢ 在 {vᵢ,…,vₙ} 中与 vᵢ 相邻的点是否构成团时间复杂度 O(nm)。优化算法设 vᵢ 在 {vᵢ,…,vₙ} 中相邻的点按序列下标从小到大为 {v_{c₁},…,v_{c_k}}则只需判断 v_{c₁} 与其他点是否直接连通即可时间复杂度 O(nm)。文档给出的优化验证代码st[s[1]]为原实现中 s[1] 的相邻点集合s[1]始终保存 rnk 最小的邻居即序列中最早出现的邻居jud true; for (int i 1; i n; i) { cur 0; for (vectorint::iterator it G[p[i]].begin(); it ! G[p[i]].end(); it) if (rnk[p[i]] rnk[*it]) { s[cur] *it; if (rnk[s[cur]] rnk[s[1]]) swap(s[1], s[cur]); } for (int j 2; j cur; j) if (!st[s[1]].count(s[j])) { jud false; break; } } if (!jud) printf(Imperfect\n); else printf(Perfect\n);这就是整条判定链的验证方式jud全程为 true、输出Perfect说明序列是完美消除序列原图是弦图任一检查失败、输出Imperfect则原图不是弦图。至此弦图判定问题在 O(nm) 时间复杂度内解决。确认为弦图后从完美消除序列读取各性质判定通过之后序列 p 已经可以当作后续一切计算的基础。以下均为文档给出的线性时间做法。求所有极大团弦图的极大团一定为 {x}N(x)这里 N(x) 指与 x 相邻且在完美消除序列上位于 x 之后的点弦图最多有 n 个极大团。判断 {x}N(x) 是否极大设 A{x}N(x)、B{y}N(y)若 A⊊B 则 A 不是极大团此时 y 在序列上位于 x 之前问题转化为判断是否存在 y 满足 nxt_yxnxt_x 为 N(x) 中序列上最靠前的点且 |N(x)|1 ≤ |N(y)|时间复杂度 O(nm)。文档代码fst存 nxtN存邻居个数vis标记被包含因而非极大的团for (int i 1; i n; i) { cur 0; for (vectorint::iterator it G[p[i]].begin(); it ! G[p[i]].end(); it) if (rnk[p[i]] rnk[*it]) { s[cur] *it; if (rnk[s[cur]] rnk[s[1]]) swap(s[1], s[cur]); } fst[p[i]] s[1]; N[p[i]] cur; } for (int i 1; i n; i) { if (!vis[p[i]]) ans; if (N[p[i]] N[fst[p[i]]] 1) vis[fst[p[i]]] true; }求色数与团数只需数值时直接取 |{x}N(x)| 的最大值for (int i 1; i n; i) ans max(ans, deg[i] 1);其中 deg[i] 为点 i 在完美消除序列上之后邻居的个数。若还需要染色方案则按完美消除序列从后往前依次给每个点染色给每个点染上可以染的最小颜色时间复杂度 O(mn)文档同时给出了 tχ(G)ω(G) 的正确性证明即该方案用掉的色数恰等于团数也等于色数。求最大独立集与最小团覆盖最大独立集沿完美消除序列从前往后选择所有与已选点没有直接连边的点。设最大独立集为 {v₁,…,v_t}则团的集合 {{vᵢ}N(vᵢ)} 就是图的最小团覆盖两者时间复杂度均为 O(nm)for (int i 1; i n; i) if (!vis[p[i]]) { ans; for (vectorint::iterator it G[p[i]].begin(); it ! G[p[i]].end(); it) vis[*it] true; }注意这段代码与极大团部分复用vis数组实际使用时两组计算应使用各自独立的标记。适用边界与可练的题上述结论只对弦图成立若验证输出Imperfect则极大团、色数等线性做法全部不可用应退回一般图算法。朴素删除单纯点法 O(n⁴)、朴素验证 O(nm) 是文档列出的复杂度基线文档的主路径MCS 优化验证 各性质计算全部为 O(nm) 级别。文档在习题一节列出了几道可用于练习的题SPOJ FISHNET、洛谷 P3196 [HNOI2008] 神奇的国度、洛谷 P3852 [TJOI2007] 小朋友可据此对照验证上面的实现。【免费下载链接】OI-wiki:star2: Wiki of OI / ICPC for everyone. 某大型游戏线上攻略内含炫酷算术魔法项目地址: https://gitcode.com/GitHub_Trending/oi/OI-wiki创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/15 19:08:27

LLM工程实例代码合集:从微调到RAG与Agent的完整基线

简介:一份聚焦2023年大模型与生成式人工智能工程实践的实例代码合集,围绕ChatGLM模型调用、LangChain应用框架使用、ChatPDF文档问答实现、向量数据库接入,以及StableDiffusion与Midjourney多模态图像生成五大专题展开,适合有一定…

2026/9/15 19:08:27

Open MCT 安全指南:威胁模型、部署防护与插件安全开发实战

Open MCT 安全指南:威胁模型、部署防护与插件安全开发实战 【免费下载链接】openmct A web based mission control framework. 项目地址: https://gitcode.com/GitHub_Trending/ope/openmct Open MCT 是一个基于浏览器的富客户端任务控制框架(We…

2026/9/15 19:03:27

如何用 npx 一键启动 camofox-browser:最快上手指南

如何用 npx 一键启动 camofox-browser:最快上手指南 【免费下载链接】camofox-browser Stealth headless browser for AI agents — bypass Cloudflare, bot detection, and anti-scraping. Drop-in Puppeteer/Playwright replacement. 项目地址: https://gitcode…

2026/9/15 4:54:30

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/15 0:01:16

AI英语单词APP开发:自适应学习算法与移动端优化实践

1. 项目概述 作为一名在移动应用开发领域摸爬滚打多年的老手,我最近完成了一个AI英语单词APP的开发项目。这个项目将传统单词记忆方法与现代AI技术相结合,打造了一款能够智能适应不同用户学习习惯的英语学习工具。 市面上大多数单词APP都存在一个通病&a…

2026/9/15 0:01:16

Flutter与OpenHarmony结合开发手语学习APP实战

1. 项目背景与核心价值作为一名同时接触过Flutter和OpenHarmony的开发者,最近我完成了一个基于Flutter for OpenHarmony的手语学习APP实战项目。这个项目最大的特点在于实现了跨平台框架与国产操作系统深度结合的创新实践——用Flutter开发的应用能完美运行在OpenHa…

2026/9/15 0:01:16

六个月成为机器人工程师:从ROS2到SLAM的实战路径

1. 六个月的紧迫感从哪来:先搞清楚你要成为哪种机器人工程师说实话,六个月的期限并不是一个宽松的时间线。市面上任何一本正经的机器人学教材都超过五百页,ROS2的官方文档可以翻到你怀疑人生,再加上ABB、KUKA这些工业机器人厂家动…

2026/9/15 14:22:53

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/14 13:53:59

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/15 11:42:23

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码