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

DeepSeek LeetCode 1489.找到最小生成树里的关键边和伪关键边 public List<List<Integer>> findCriticalAndPseudoCritical

本题要求找出无向加权图中所有最小生成树(MST)的关键边和伪关键边。关键边出现在所有MST中,伪关键边出现在某些但非全部MST中。

算法思路

1. 计算原图的最小生成树权重
使用Kruskal算法(并查集)求出任意一个MST的总权重 originalWeight。
2. 逐边判断
对每条边 i:
· 关键边判断:忽略该边,计算剩余图的MST权重。若结果大于 originalWeight 或图不连通,说明该边必须存在于所有MST中,即为关键边。
· 伪关键边判断:若非关键边,则强制将该边加入图中,再计算MST。若得到的权重等于 originalWeight,说明该边可以出现在某个MST中,即为伪关键边。
3. 返回结果
关键边索引列表和伪关键边索引列表。

复杂度分析

· 时间复杂度:O(E²·α(V)),其中 E ≤ 200,V ≤ 100,可以接受。
· 空间复杂度:O(E + V)。

Java代码

```java
import java.util.*;

class Solution {
class Edge implements Comparable<Edge> {
int u, v, weight, idx;
Edge(int u, int v, int weight, int idx) {
this.u = u; this.v = v; this.weight = weight; this.idx = idx;
}
@Override
public int compareTo(Edge other) {
return this.weight - other.weight;
}
}

public List<List<Integer>> findCriticalAndPseudoCriticalEdges(int n, int[][] edges) {
int m = edges.length;
List<Edge> edgeList = new ArrayList<>();
for (int i = 0; i < m; i++) {
edgeList.add(new Edge(edges[i][0], edges[i][1], edges[i][2], i));
}
// 按权重排序,后续每次MST计算使用这个排序列表
Collections.sort(edgeList);

int originalWeight = kruskal(n, edgeList, -1, -1);

List<Integer> critical = new ArrayList<>();
List<Integer> pseudo = new ArrayList<>();

for (int i = 0; i < m; i++) {
// 忽略边i,判断是否为关键边
int weightWithout = kruskal(n, edgeList, i, -1);
if (weightWithout > originalWeight) {
critical.add(i);
continue;
}
// 强制包含边i,判断是否为伪关键边
int weightWith = kruskal(n, edgeList, -1, i);
if (weightWith == originalWeight) {
pseudo.add(i);
}
}

return Arrays.asList(critical, pseudo);
}

private int kruskal(int n, List<Edge> edges, int skipIdx, int forceIdx) {
UnionFind uf = new UnionFind(n);
int totalWeight = 0;
int edgeCount = 0;

// 强制包含某条边
if (forceIdx != -1) {
Edge e = null;
for (Edge edge : edges) {
if (edge.idx == forceIdx) {
e = edge;
break;
}
}
// 如果两端已连通,则无法形成MST
if (!uf.union(e.u, e.v)) {
return Integer.MAX_VALUE;
}
totalWeight += e.weight;
edgeCount++;
}

// 正常Kruskal
for (Edge e : edges) {
if (e.idx == skipIdx || e.idx == forceIdx) continue;
if (uf.union(e.u, e.v)) {
totalWeight += e.weight;
edgeCount++;
if (edgeCount == n - 1) break;
}
}

return edgeCount == n - 1 ? totalWeight : Integer.MAX_VALUE;
}

class UnionFind {
int[] parent, rank;
UnionFind(int n) {
parent = new int[n];
rank = new int[n];
for (int i = 0; i < n; i++) parent[i] = i;
}
int find(int x) {
if (parent[x] != x) parent[x] = find(parent[x]);
return parent[x];
}
boolean union(int x, int y) {
int rx = find(x), ry = find(y);
if (rx == ry) return false;
if (rank[rx] < rank[ry]) parent[rx] = ry;
else if (rank[rx] > rank[ry]) parent[ry] = rx;
else { parent[ry] = rx; rank[rx]++; }
return true;
}
}
}
```

http://www.jsqmd.com/news/659893/

相关文章:

  • 汽车 ECU “一芯一证” 实现详解:头部车企四级密钥体系实践
  • 2026年生命科学科研试剂公司口碑排行,聚顶生物公司介绍来啦 - mypinpai
  • SLG大地图实战:从Tilemap到Shader的地表渲染与数据分层架构
  • 最全话费卡快捷回收攻略,轻松实现现金变现! - 团团收购物卡回收
  • 【Java】继承:从入门到JVM底层,一篇搞定
  • Windows Cleaner终极方案:一键解决C盘爆红难题的智能清理工具
  • 零配置部署mPLUG视觉问答:一键启动,开箱即用的图片分析工具
  • Driver Store Explorer:5分钟掌握Windows驱动管理,轻松释放10GB+磁盘空间
  • SAP 组织与核算要素关系清单(含层级、归属、数据流向、关键T-code)
  • Comics Downloader终极指南:8大漫画网站一键离线下载,打造个人漫画图书馆
  • NVIDIA Profile Inspector 2.4.0.1:解锁NVIDIA显卡隐藏性能的终极指南
  • Coze-Loop与Dify平台集成:全栈AI应用开发优化
  • 3048基于单片机的直流电机角度速度控制系统设计(数码管,矩阵键盘)
  • RWKV7-1.5B-G1A Java开发实战:集成SpringBoot构建智能微服务
  • javascript:void(0) 含义
  • 【THM-课程内容】:Privilege Escalation-Windows Privilege Escalation:Abusing dangerous privileges
  • LLM工程化实践——RAG基础入门(一)
  • Bitbucket代码仓库全流程指南:从创建到分支管理与忽略文件配置
  • GEO Monitor Toolkit:让你知道 AI 模型在背后怎么评价你
  • SAP 组织与核算要素全景梳理(含架构、关系、数据流转)
  • ComfyUI-VideoHelperSuite三阶架构设计:基于FFmpeg的模块化视频处理引擎
  • TR-B | 中南-北航团队:连续通勤走廊早高峰均衡,终于完整破解!
  • 飞书文档批量导出工具:从手动复制到自动化迁移的完整解决方案
  • C语言中将数字转换为字符串的方法
  • 013、Python条件判断:if、elif、else语句
  • 轻量模型不妥协:all-MiniLM-L6-v2在Ollama中保持92%+ STS-B准确率
  • 从原理到实战:深度剖析Apache Shiro Remember Me反序列化漏洞(CVE-2016-4437)的攻防博弈
  • GitHub中文界面插件终极指南:3分钟让你的GitHub全面中文化
  • 沈阳小程序制作终极攻略:2026 年精准锁定最佳开发团队
  • AI 技术日报 - 2026-04-18