这题一看显然是一个裸的斯坦纳树

我们用$f[i][j]$表示经过的路径中包含了状态$i$所表示的点,且连接了$j$号点的最短路径。

显然,$f[i][j]=min\{f[i$^$k][j]+f[k][j]\}$, 其中$i $&$ k = k$。

转移完毕后,跑一个最短路去更新一遍。

那么显然这题的时间复杂度是$O(2^k\times 最短路时间复杂度)$。

但是这题神TM卡SPFA。。。。

我后来改写了$dij$,再加了个避免重复更新的判断,才过了...

 #include<bits/stdc++.h>
#define M 100005
#define L long long
#define INF 1926081719260817LL
using namespace std;
struct edge{int u,v,next;}e[M<<]={}; int head[M]={},use=;
void add(int x,int y,int z){use++;e[use].u=y;e[use].v=z;e[use].next=head[x];head[x]=use;}
L f[<<][M]={};
struct node{
int u; L dis; node(){u=dis=;}
node(int uu,L diss){u=uu; dis=diss;}
friend bool operator <(node a,node b){return a.dis>b.dis;}
}; priority_queue<node> q;
bool vis[M]={};
void spfa(L dfn[]){
memset(vis,,sizeof(vis));
while(!q.empty()){
node uu=q.top(); q.pop();
int u=uu.u;
if(vis[u]) continue; vis[u]=;
for(int i=head[u];i;i=e[i].next)
if(dfn[e[i].u]>dfn[u]+e[i].v){
dfn[e[i].u]=dfn[u]+e[i].v;
q.push(node(e[i].u,dfn[e[i].u]));
}
}
}
int n,m,k,p[]={}; int main(){
scanf("%d%d%d",&n,&k,&m);
for(int i=;i<(<<k);i++)
for(int j=;j<=n;j++) f[i][j]=INF;
for(int i=;i<k;i++){
scanf("%d",p+i);
f[<<i][p[i]]=;
}
for(int i=;i<=m;i++){
int x,y,z; scanf("%d%d%d",&x,&y,&z);
add(x,y,z); add(y,x,z);
}
for(int i=;i<(<<k);i++){
for(int j=i;j;j=i&(j-)){
for(int k=;k<=n;k++)
f[i][k]=min(f[i][k],f[j][k]+f[i^j][k]);
}
for(int k=;k<=n;k++)
if(f[i][k]!=INF) q.push(node(k,f[i][k]));
spfa(f[i]);
}
L minn=INF;
for(int i=;i<=n;i++)
minn=min(minn,f[(<<k)-][i]);
cout<<minn<<endl;
}

【bzoj5180】[Baltic2016]Cities 斯坦纳树的更多相关文章

  1. [bzoj2595][WC2008]游览计划/[bzoj5180][Baltic2016]Cities_斯坦纳树

    游览计划 bzoj-2595 wc-2008 题目大意:题目链接.题目连接. 注释:略. 想法:裸题求斯坦纳树. 斯坦纳树有两种转移方式,设$f[s][i]$表示联通状态为$s$,以$i$为根的最小代 ...

  2. BZOJ_5180_[Baltic2016]Cities_ 斯坦纳树

    BZOJ_5180_[Baltic2016]Cities_ 斯坦纳树 题意: 给定n个点,m条双向边的图.其中有k个点是重要的.每条边都有一定的长度. 现在要你选定一些边来构成一个图,要使得k个重要的 ...

  3. 初涉斯坦纳树&&bzoj4774: 修路

    斯坦纳树的基础应用 斯坦纳树有什么用 个人一点粗浅理解…… 最基本形式的斯坦纳树问题(以下简称母问题):给定图G和一个关键点集V.求在G中选取一个权值最小(这里权值可以有很多变式)的边集E使V中的点两 ...

  4. BZOJ 5180 [Baltic2016]Cities(斯坦纳树)

    斯坦纳树的板子题. 斯坦纳树问题是组合优化问题,与最小生成树相似,是最短网络的一种. 最小生成树是在给定的点集和边中寻求最短网络使所有点连通. 而最小斯坦纳树允许在给定点外增加额外的点,使生成的最短网 ...

  5. 【BZOJ2595】游览计划(状压DP,斯坦纳树)

    题意:见题面(我发现自己真是越来越懒了) 有N*M的矩阵,每个格子有一个值a[i,j] 现要求将其中的K个点(称为关键点)用格子连接起来,取(i,j)的费用就是a[i,j] 求K点全部连通的最小花费以 ...

  6. HDU 4085 斯坦纳树

    题目大意: 给定无向图,让前k个点都能到达后k个点(保护地)中的一个,而且前k个点每个需要占据后k个中的一个,相互不冲突 找到实现这个条件达到的选择边的最小总权值 这里很容易看出,最后选到的边不保证整 ...

  7. hdu4085 Peach Blossom Spring 斯坦纳树,状态dp

    (1)集合中元素表示(1<<i), i从0开始 (2)注意dp[i][ss] = min(dp[i][ss], dp[i][rr | s[i]] + dp[i][(ss ^ rr) | s ...

  8. hdu 3311 斯坦纳树

    思路:虚拟一个0号节点,将每个点建一条到0号节点的边,权值为挖井需要的价值.并要保证0号节点同另外n个寺庙一样被选择即可. 然后就是求斯坦纳树了. #include<map> #inclu ...

  9. HDU 3311 Dig The Wells(斯坦纳树)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3311 [题意] 给定k座庙,n个其他点,m条边,点权代表挖井费用,边权代表连边费用,问使得k座庙里 ...

随机推荐

  1. 2018.08.18 NOIP模拟 snow(最大流)

    Snow 题目背景 SOURCE:NOIP2015-SHY4 题目描述 有一天,TT 要去 ABC 家.ABC 的大门外有 n 个站台,用 1 到 n 的正整数编号,TT 需要对每个站台访问恰好一定次 ...

  2. SQL之经典SQL语句大全

    经典SQL语句大全 一.基础 1.说明:创建数据库CREATE DATABASE database-name 2.说明:删除数据库drop database dbname3.说明:备份sql serv ...

  3. 编译hbase-1.2.3源代码

    目录 目录 1 1. 约定 1 2. 安装jdk 1 3. 安装maven 1 4. 网络配置 2 4.1. eclipse 3 4.2. maven 3 5. 从hbase官网下载源代码包: 4 6 ...

  4. Git 同步远程仓库

    在你经常使用的命令当中有一个git branch –a 用来查看所有的分支,包括本地和远程的.但是时间长了你会发现有些分支在远程其实早就被删除了,但是在你本地依然可以看见这些被删除的分支. 同步远程分 ...

  5. jmeter 5.0版本更新说明(个人做个记录)

    变化   此页面仅详细说明了当前版本中所做的更改. 先前更改的历史记录中详细介绍了早期更改.   5.0版 摘要 新的和值得注意的 不兼容的变化 Bug修复 改进 非功能性变化 已知问题和解决方法 谢 ...

  6. 19、Docker Compose

      编排(Orchestration)功能是复杂系统实现灵活可操作性的关键.特别是docker应用场景中,编排意味着用户可以灵活地对各种容器资源实现定义和管理.   在我们部署多容器的应用时: 要从D ...

  7. 转载:<context-param>与<init-param>的区别与作用

    <context-param>的作用:web.xml的配置中<context-param>配置作用1.启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件web ...

  8. Python学习-36.Python中的字典解释

    具体同列表解释,也是使用if来进行过滤 例子,生成一个新的字典,并且是原来字典的键值交换. mydict={'Tom':18,'Mary':20} print({value:key for key,v ...

  9. 常用kubectl命令总结

    command kubectl kubectl 输出格式 显示Pod的更多信息 kubectl get pod <pod-name> -o wide 以yaml格式显示Pod的详细信息 k ...

  10. Python 数据结构与算法——冒泡排序

    #方法一:递归 def bubble(lst,i): if i==1: return lst for j in range(i-1): if lst[j] > lst[j+1]: lst[j], ...