最小斯坦纳树 学习笔记

news/2024/9/16 3:32:26/文章来源:https://www.cnblogs.com/dccy/p/18397370

最小斯坦纳树

给定一张无相连通图,每条边有权值,有 \(k\) 个关键点,要求选择权值和最小的边使得关键点连通,求权值和。

类似最小生成树,但是限定了关键点就只能用指数级的复杂度解决,这里考虑类似状压 DP 的方法。

例题:P6192 【模板】最小斯坦纳树

首先最终答案显然是一个树。

所以我们设 \(f_{i,S}\) 表示以 \(i\) 为根的树,包含了关键点中 \(S\) 的这些点,\(S\) 是一个 \(01\) 串。

考虑怎么转移,分 \(i\) 的度数为 \(1\),和不为 \(1\) 两种情况。

\(1\) 则:

\[f_{i,S}+w(i,j)\rightarrow f_{j,S} \]

不为 \(1\)\(i\) 有两个子树,把两个子树合并即可:

\[f_{i,S}+f_{i,T}\rightarrow f_{i,S+T} \]

要注意在这里我们不用关心 \(i,j\) 是否是关键点而更新后面的 \(S\),我们只需在最开始把关键点 \(i\) 赋为 \(f_{i,\{i\}}=0\) 即可,然后后面的转移相当于把这些关键点合并。

由于 \(S\) 肯定是逐渐变大的,所以考虑在最外层枚举 \(S\),用之前的状态更新当前的状态,这里是 \(O(2^k)\)

考虑怎么实现,对于上面一条转移,注意我们不是只做一条边,可能是很多条边连起来,那么就做最短路,用优先队列 \(Dijkstra\) 可以做到 \(O(n\log m)\),具体地就是一开始把所有点都推进队列里,总的就是 \(O(2^k n\log m)\)

对于下面这条转移,就是一个枚举子集,而枚举子集可以做到 \(3^k\),具体来说是这样(\(j\)\(i\) 的子集):

for(int i=0;i<(1<<k);i++)for(int j=i;j;j=((j-1)&i))do something

所以这一部分的总复杂度是 \(O(3^k n)\)

注意一件事情,我们需要先做度数不为 \(1\) 的转移,再做为 \(1\) 的转移,相当于是先得到更大的 \(S\),然后才能把这个 \(S\) 扩展到更多的点;否则若更大的 \(S\) 还没合并,不是最优的,那么先扩展到更多的点也不是最优的。

最后的复杂度就是 \(O(3^kn+2^k n\log m)\)

AC 代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,K;
const int N=105,M=505;
vector<pair<int,int>> g[N];
int f[N][1<<10],bz[N];
struct arr{int val,num;arr(int _val,int _num){val=_val,num=_num;}
};
int operator<(arr x,arr y){return x.val>y.val;
}
int id[N];
int main(){
//	freopen("P.in","r",stdin);ios::sync_with_stdio(0);cin>>n>>m>>K;	for(int i=1;i<=m;i++){int u,v,w;cin>>u>>v>>w;g[u].push_back(make_pair(v,w));g[v].push_back(make_pair(u,w));}int X;memset(f,0x3f,sizeof f);for(int i=1;i<=K;i++){int x; cin>>x;X=x; id[x]=i;f[x][1<<i-1]=0;}for(int i=1;i<(1<<K);i++){for(int j=i;j;j=((j-1)&i)){for(int k=1;k<=n;k++)f[k][i]=min(f[k][i],f[k][j]+f[k][i-j]);}memset(bz,0,sizeof bz);priority_queue<arr> q;for(int k=1;k<=n;k++)q.push(arr(f[k][i],k));while(q.size()){int u;while(q.size()&&bz[u=q.top().num])q.pop();if(q.empty())break;bz[u]=1; q.pop();for(auto _v:g[u]){int v=_v.first,co=_v.second;if(f[v][i]>f[u][i]+co){f[v][i]=f[u][i]+co;q.push(arr(f[v][i],v));}}}}cout<<f[X][(1<<K)-1];
}

相关练习

P4294 [WC2008] 游览计划

P3264 [JLOI2015] 管道连接

P3638 [APIO2013] 机器人

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/792293.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于迭代扩展卡尔曼滤波算法的倒立摆控制系统matlab仿真

1.课题概述基于迭代扩展卡尔曼滤波算法的倒立摆控制系统,对比UKF,EKF迭代UKF,迭代EKF四种卡尔曼滤波的控制效果。2.系统仿真结果 3.核心程序与模型 版本:MATLAB2022a%迭代扩展卡尔曼滤波 X_iukf = zeros(2, Times1); X_iukf(:,1) = state0; P_iukf = zeros(2…

支持大模型的小模型

https://www.arxiv.org/pdf/2408.12748 (SLM Meets LLM: Balancing Latency, Interpretability and Consistency in Hallucination Detection )平衡会话 AI 幻觉检测中的延迟、可解释性和一致性 介绍 大型语言模型(llm)在实时任务(如同步的会 话 ui)中与延迟作斗争。 当额外的…

基于颜色模型和边缘检测的火焰识别FPGA实现,包含testbench和matlab验证程序

1.算法运行效果图预览 (完整程序运行后无水印)将FPGA仿真结果导入到matlab显示结果:测试样本1测试样本2测试样本32.算法运行软件版本 vivado2019.2matlab2022a3.部分核心程序 (完整版代码包含注释和操作步骤视频)`timescale 1ns / 1ps // // Company: // Engineer: // //…

exkmp/Z函数

扩展 KMP/exKMP(Z 函数) 首先我们求出 \(ne\) 数组。代表 \(b\) 与 \(b\) 的每一个后缀的最长公共前缀长度。 我们设当前要求 \(ne_x\),且 \(k\) 为使得 \(p=k+ne_k-1\) 最大的位置且 \(0\le k<x\)。于是我们得到了两个蓝块相同。再通过这个图,得出两个绿块相等。

群晖搭建个人图书馆

概述 本文依赖于 github 项目 talebook (https://github.com/talebook ) 本文依赖于 github 项目(GitHub - cxfksword/douban-api-rs: 简单的豆瓣api,主要用于在jellyfin中刮削电影信息) 其实就是面向于新手的个人图书馆项目搭建,但是作者本人也是新手[/笑哭]。 搭建 tale…

业务类中处理点赞、收藏和浏览量

在对点赞、收藏和浏览量进行操作时,获取分布式锁,以确保并发情况下数据的准确性。 先更新缓存,然后将更新数据库的操作放入消息队列中异步处理,以提高响应速度。 缓存预热 在系统启动或定期将热门文章的相关数据加载到缓存中,减少首次访问时的数据库查询。描述 点赞、收藏…

极速全景图下载出错显示Permission denied怎么回事

在极速全景图下载大师下载拼接全景图的过程中, 出现了错误, 提示错误信息: creating file kvmem_xxxxx_xxxxx.swap failed: Permission denied (errno=13)经过排查, 上述错误是由以下原因导致的: - 系统运行内存不足, 导致在拼接过程无法创建缓存文件, 导致出错 解决方案: 检查…

关于园子求救信有感

毕业七年了,写了七年的博客,养成了记录的习惯。7年写了800篇随笔,很杂。前端,java,mysql,linux,php用到啥学啥,学到啥就记录啥。 最近不是很好,工作且算顺利,七年的爱情摇摇欲坠,未来很是模糊,说起来有写记录的习惯也是源于恋爱日记,现在看来全是泪啊。 前几天,看…

一个开源、跨平台的.NET UI框架 - Avalonia UI

前言 今天大姚给大家分享一个开源、免费(MIT License)、跨平台的.NET UI框架:Avalonia UI。Avalonia是一个成熟稳定的平台,用于构建桌面、嵌入式、移动的和Web应用程序。一个代码库,无限可能!!!项目介绍 Avalonia是一个强大的框架,使开发人员能够使用.NET创建跨平台应用程…

Jenkins Job 构建动态参数配置

在做jenkins项目时,有些参数不是固定写死的,而是动态变化的,这时我们可以用 Active Choices 插件来远程调用参数。 实现结果如下:操作步骤:注意筛选关键字参数必须位于筛选列表的前面,如该文章示例keyword必须在affectedPlatformIds前面 Groovy Script代码如下:import …

Latex使用中文或中英文混合使用

如果想显示中文内容或者中英文混用在开头部分添加包 \usepackage{xeCJK} 随后在设置中将编译方式改成 XeLaTex 即可。注意:可能与pdfLaTex编译方式产生的结果有区别。