title : 斯坦纳树
tags : ACM 图论
date : 2021-6-26
author : Linno


什么是斯坦纳树

给定 n 个点 A1,A2,⋯,An试求连接此n个点,总长最短的直线段连接系统,并且任意两点都可由系统中的直线段组成的折线连接起来。他们将此新问题称为 斯坦纳树问题
斯坦纳树问题是组合优化问题,与最小生成树相似,是最短网络的一种。最小生成树是在给定的点集和边中寻求最短网络使所有点连通。而最小斯坦纳树允许在给定点外增加额外的点,使生成的最短网络开销最小。

将指定点集合中的所有点连通,且边权总和最小的生成树称为最小斯坦纳树(Minimal Steiner Tree)

算法推导

这是一个组合优化问题,可以用状压DP来解决。

首先有已经结论:答案的子图一定是树。

我们首先钦定一个树根,设dp(i,S)表示以i为根,包含S点集的最小代价。

考虑状态转移:
若i的度数等于1,则dp(j,s)+w(j,i)−>dp(i,s)若i的度数大于1,则dp(i,T)+dp(i,S−T)−>dp(i,S)(T⊆S)若i的度数等于1,则dp(j,s)+w(j,i)->dp(i,s)\\ 若i的度数大于1,则dp(i,T)+dp(i,S-T)->dp(i,S)(T\subseteq S) 若i的度数等于1,则dp(j,s)+w(j,i)−>dp(i,s)若i的度数大于1,则dp(i,T)+dp(i,S−T)−>dp(i,S)(T⊆S)
状态转移时对每个S,将图做松弛操作,采用dijkstra实现。

总的时间复杂度 O(n×3k+mlogm×2k)O(n×3^k+mlog m ×2^k)O(n×3k+mlogm×2k)

(洛谷P6192【模板】最小斯坦纳树 图示)
代码
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f3f3f3f
using namespace std;
const int maxn=510;
const int INF=0x3f3f3f3f;
typedef long long ll;
typedef pair<int,int> P;
int n,m,k,u,v,w;
struct E{int to,next,dis;
}edge[maxn<<1];int head[maxn<<1],tree[maxn<<1],cnt;
int dp[maxn][5005],vis[maxn];
//dp[i][j]表示以i为根的一棵树,包含集合j中所有点的最小边权值和
int key[maxn];  //关键点
priority_queue<P,vector<P>,greater<P> >q;void addedge(int from,int to,int dis){edge[++cnt].next=head[from];edge[cnt].to=to;edge[cnt].dis=dis;head[from]=cnt;tree[cnt]=to;
}void dijkstra(int s){  //迪杰斯特拉堆优化算法 memset(vis,0,sizeof(vis));while(!q.empty()){P fro=q.top();q.pop();    if(vis[fro.second]) continue;vis[fro.second]=1;for(int i=head[fro.second];i;i=edge[i].next){if(dp[tree[i]][s]>dp[fro.second][s]+edge[i].dis){dp[tree[i]][s]=dp[fro.second][s]+edge[i].dis;//再当前子集连通状态下进行边的松弛操作 q.push(P(dp[tree[i]][s],tree[i]));}}}
} signed main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);memset(dp,INF,sizeof(dp));cin>>n>>m>>k;for(int i=1;i<=m;i++){ //建无向图 cin>>u>>v>>w;addedge(u,v,w);addedge(v,u,w);}for(int i=1;i<=k;i++){cin>>key[i]; dp[key[i]][1<<(i-1)]=0;}for(int s=1;s<(1<<k);s++){ //表示点集for(int i=1;i<=n;i++){  //中间部分for(int subs=s&(s-1);subs;subs=s&(subs-1)) //子图 dp[i][s]=min(dp[i][s],dp[i][subs]+dp[i][s^subs]);if(dp[i][s]!=INF) q.push(P(dp[i][s],i));  }dijkstra(s);}cout<<dp[key[1]][(1<<k)-1]<<endl;return 0;
}

参考资料

https://www.luogu.com.cn/problem/solution/P6192

【算法竞赛学习笔记】超好懂的斯坦纳树详解!!!相关推荐

  1. Ext.Net学习笔记22:Ext.Net Tree 用法详解

    上面的图片是一个简单的树,使用Ext.Net来创建这样的树结构非常简单,代码如下: <ext:TreePanel runat="server"><Root> ...

  2. python列表和元组的应用_python学习笔记之列表(list)与元组(tuple)详解

    前言 最近重新再看python的基础知识,感觉自己还是对于这些知识很陌生,需要用的时候还是需要翻书查阅,还是先注重基础吧--我要重新把python的教程阅读一遍,把以前自己忽略的部分学习,加强练习和记 ...

  3. 【Azure 架构师学习笔记】-Azure Data Factory (4)-触发器详解-事件触发器

    本文属于[Azure 架构师学习笔记]系列. 本文属于[Azure Data Factory]系列. 接上文[Azure 架构师学习笔记]-Azure Data Factory (3)-触发器详解-翻 ...

  4. 【matcovnet学习笔记】objective,top1error,top5error详解

    [matcovnet学习笔记]objective,top1error,top5error详解 排名前1和前5的错误率是衡量某些解决方案成功与否的重要单位 ,要理解这三个概念,关键是要看懂下面这个多类误 ...

  5. 【算法竞赛学习笔记】状压DP

    title : 状压DP date : 2022-3-5 tags : ACM,图论,动态规划 author : Linno 状压DP 状态压缩,是利用二进制数的性质对问题进行优化的一种算法,经常与搜 ...

  6. 【算法竞赛学习笔记】pb_ds-超好懂的数据结构

    title : pb_ds date : 2021-8-21 tags : ACM,数据结构 author : Linno 简介 pb_ds库全称Policy-Based Data Structure ...

  7. 【算法竞赛学习笔记】快速傅里叶变换FFT-数学提高计划

    tilte : 快速傅里叶变换FFT学习笔记 tags : ACM,数论 date : 2021-7-18 简介 FFT(Fast Fourier Transformation),中文名快速傅里叶变换 ...

  8. 【C++】【学习笔记】【递归与回溯问题详解与例题】排列问题;组合问题;二维平面回溯;flood fill问题;搜索问题(八皇后);

    目录 七.递归和回溯 1.回溯 2.回溯应用 - 排列问题 2.回溯应用 - 组合问题 3.回溯应用 - 二维平面 4.回溯应用 - floodfill算法 问题 4.回溯应用 - 搜索问题 - 八皇 ...

  9. Apollo星火计划学习笔记——第四讲Part2 Apollo定位模块详解与实践

    引言 内容概要,学习目标 了解自动驾驶定位的作用 熟悉常见的自动驾驶定位方法 掌握整个Apollo定位模块框架 独立开发定位模块 1. 定位的作用 1.1 定位及其相关知识点 定位: 获取当前的地理位 ...

最新文章

  1. jQuery-拖动层(在可视区域范围内)
  2. 计算机科普知识小动画,4岁嗯哼知识量惊呆杜江!这4部科普启蒙动画,孩子绝对不能错过...
  3. 堆密度测定的意义_堆密度的测量
  4. MMN实用架构过程概览
  5. 【数据结构与算法】【算法思想】【算法总结】索引结构
  6. ASCII Unicode GBK UTF的联系
  7. 关于SVG的viewBox
  8. sqoop数据导出导入命令
  9. 【人工智能】“看透”神经网络
  10. python判断回文_Python实现判断一个整数是否为回文数算法示例
  11. CentOS-FTP
  12. 从1.5K到18K 一个程序员的5年成长之路
  13. 软件定义网络:昨天今天明天
  14. Windows下LaTeX安装教程
  15. Tuxedo中间件常用命令
  16. 服务器没有D盘怎么架设传奇?
  17. html 实现蒙板效果,用css3实现ps蒙版效果+动画
  18. 为什么华为a1路由器网速变慢_华为路由器上网速度慢怎么办?
  19. 【设计】电压电流偏置
  20. “热散由心静,凉生为室空” - linux温控的那些事儿

热门文章

  1. Minecraft 1.19.2 Fabric模组开发 10.建筑生成
  2. CentOS8主机名设置方式
  3. 19c 数据高可用实用配置 RAC + SingleADG
  4. 解决 golang json 中 invalid character ‘\r‘ in string literal 报错
  5. List 1 17.02.07
  6. php imagick 扩展,PHP使用imagick扩展实现合并图像的方法详解
  7. AssetBundle打包以及游戏更新
  8. 电力电子变压器。 整流级采用级联H桥多电平拓扑,由三个H桥模块级联,将工频交流转换为直流
  9. 基于杂草优化算法的线性规划问题求解matlab程序
  10. 文件大小分门别类”:如何利用简单的方法对你的文件进行分类整理!