次小生成树——转载于张鹏飞博客

本文介绍了次小生成树的概念及其实现方法。首先通过变换视角证明了次小生成树可由最小生成树更换一条边得到。接着详细阐述了算法的具体步骤,并提供了实现思路。

一.理论准备

需要读者事先懂得prime算法,不太了解的请看博主这一篇http://www.cnblogs.com/hxsyl/p/3286956.html,也需要读者对DP了解一些。

先看一个结论:次小生成树可由最小生成树换一条边得到

     证明:咱换种方式去看待这个结论(一个生成树可以通过换边得到另一个生成树),T是某一棵最小生成树,T0是任一棵异于T的生成树,通过变换T0 --> T1 --> T2 --> ... --> Tn (T)  变成最小生成树。所谓的变换是,每次把Ti中的某条边换成T中的一条边, 而且树T(i+1)的权小于等于Ti的权。
     step 1. 在Ti中任取一条不在T中的边uv. 
     step 2. 把边uv去掉,就剩下两个连通分量A和B,在T中,必有唯一的边u'v' 连结A和B。这是为什么呢?因为生成树中任意两点间只有一条路径(下面也要用这个),且必有一条。 
     step 3. 显然u'v'的权比uv小 (prime算法贪心的,否则,uv就应该在T中),把u'v'替换uv即得树T(i+1)。 
     特别地:取T0为任一棵次小生成树,T(n-1) 也就是次小生成树且跟T差一条边, 结论得证。

二.具体步骤


step 1. 先用prim求出最小生成树T,在prim的同时,用一个矩阵maxd[u][v] 记录 在T中连结任意两点u,v的唯一的路中权值最大的那条边的权值.(有些拗口),这是很容易做到的,因为prim是每次增加一个结点s, 在此需要保存节点和其父节点,采用DP,则最大权值要么是新加入的边,要么是父节点到起始点的采用DP算出来的距离,如下:

//u是刚加入的点,不过还没进入节点数组,v是已经存在的点
//min是按prime新加入那条边
maxd[v][u] = maxd[u][v] = max{min,maxd[father[u]][v]} 该步骤用时 O(V^2),就是prime算法的耗时。
step 2. 枚举所有不在T中的边uv, 加入边uv则必然替换权为maxd[u][v]的边,这样才能保证次小。

三.算法实现


    只要最小生成树和次小生成树权值和一样就唯一。因此得出如下算法,首先计算出最小生成树T,然后对最小生成树上任意不相邻的两个点 uv添加最小生成树以外的存在的边形成环,然后寻找u与v之间最小生成树上最长的边删去,计算map[i][j]与 maxd[i][j差值,求出最小的来,如果是0,就说明MST和次小生成树一样。
2025-06-10 19:14:50,966 ERROR 10208 nodejs.TypeError: Cannot read properties of undefined (reading 'config') at new BaseContextClass (C:\Users\张鹏飞\Desktop\electron项目开发\desktop-applications\node_modules\ee-core\controller\baseContextClass.js:25:23) at new Logins (C:\Users\张鹏飞\Desktop\electron项目开发\desktop-applications\electron\controller\example.js:8:5) at Index.ready (C:\Users\张鹏飞\Desktop\electron项目开发\desktop-applications\electron\index.js:17:29) at Index.initialize (C:\Users\张鹏飞\Desktop\electron项目开发\desktop-applications\node_modules\ee-core\ee\application.js:92:16) at process.processTicksAndRejections (node:internal/process/task_queues:96:5) pid: 10208 hostname: 飞翔 (node:10208) UnhandledPromiseRejectionWarning: TypeError: Cannot read properties of undefined (reading 'config') at new BaseContextClass (C:\Users\张鹏飞\Desktop\electron项目开发\desktop-applications\node_modules\ee-core\controller\baseContextClass.js:25:23) at new Logins (C:\Users\张鹏飞\Desktop\electron项目开发\desktop-applications\electron\controller\example.js:8:5) at Index.ready (C:\Users\张鹏飞\Desktop\electron项目开发\desktop-applications\electron\index.js:17:29) at Index.initialize (C:\Users\张鹏飞\Desktop\electron项目开发\desktop-applications\node_modules\ee-core\ee\application.js:92:16) at process.processTicksAndRejections (node:internal/process/task_queues:96:5) (Use `electron --trace-warnings ...` to show where the warning was created) 报错呀
最新发布
06-11
### 解决 `electron-egg` 框架中 `TypeError: Cannot read properties of undefined (reading 'config')` 的问题 在 `electron-egg` 框架中,出现 `TypeError: Cannot read properties of undefined (reading 'config')` 的错误通常表明代码尝试访问一个未定义的对象的属性 `config`。以下是可能的原因及解决方案: #### 1. 确保 `Application` 类正确初始化 错误可能源于 `Application` 类未正确初始化上下文丢失。在 `Index` 类中,构造函数调用了父类 `Application` 的构造函数,但如果没有正确传递上下文,可能会导致 `this.config` 为 `undefined`。 ```javascript class Index extends Application { constructor() { super(); // 确保正确调用父类构造函数 if (!this.config) { throw new Error('Config is not initialized'); // 如果 config 未初始化,抛出错误[^1] } } } ``` #### 2. 配置文件加载失败 如果配置文件未正确加载,`this.config` 可能为空。检查配置文件路径是否正确以及文件内容是否符合预期。 ```javascript const path = require('path'); const { Config } = require('ee-core'); class Index extends Application { constructor() { super(); const configPath = path.resolve(__dirname, './config/default.js'); // 确保配置文件路径正确 this.config = new Config(configPath); } } ``` #### 3. 上下文丢失 在异步回调中使用箭头函数可以避免上下文丢失。例如,在 `ready` 方法中创建控制器实例时,确保 `this` 指向正确的对象。 ```javascript async ready() { console.log('ee-core app is ready'); const loginController = new Logins(this.ctx); // 确保 this.ctx 正确传递[^2] await loginController.createWindow({ type: 'vue', content: '/login', windowName: 'login', windowTitle: '请登录' }); } ``` #### 4. 检查依赖模块的正确性 如果 `ee-core` 其他依赖模块未正确安装版本不匹配,也可能导致此类错误。尝试重新安装依赖并清理缓存。 ```bash rm -rf node_modules package-lock.json npm install ``` #### 5. 调试与日志记录 通过添加日志记录,可以更清晰地定位问题所在。在关键位置打印变量值以确认其状态。 ```javascript async ready() { console.log('ee-core app is ready'); console.log('Current config:', this.config); // 打印当前配置以确认是否加载成功[^3] if (!this.config) { throw new Error('Config is not defined'); } const loginController = new Logins(this.ctx); await loginController.createWindow({ type: 'vue', content: '/login', windowName: 'login', windowTitle: '请登录' }); } ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值