初涉斯坦纳树&&bzoj4774: 修路
斯坦纳树的基础应用
斯坦纳树有什么用
个人一点粗浅理解……
最基本形式的斯坦纳树问题(以下简称母问题):给定图G和一个关键点集V。求在G中选取一个权值最小(这里权值可以有很多变式)的边集E使V中的点两两连通。
由于这个母问题只对关键点有限制。那么可以用状压dp的做法:$f[i][j]$表示对于$i$点而言,它已连通的关键点状态为$j$的最小代价。
那么$f[i][j]$就有两种转移方式:1.从$f[i][t]$转移而来;2.从$f[v][j]$转移而来。
注意到第一种转移就相当于枚举子集;第二种转移形如最短路问题。那么只需要每次额外对于第二种转移做一遍最短路即可。
最终的时间复杂度为$O(n*3^k)$。
相关博客:
1.【bzoj5180】[Baltic2016]Cities 斯坦纳树
【dp套斯坦纳树】bzoj4774: 修路
Description
Input
Output
题目分析
不同的是,这里只要求$i$和$n-i+1$连通。
用$f[i][j]$表示对于$i$节点,$2d$个点的连通状态为$j$时的最小代价。另用$g[t]$表示全局$t$状态时的最小代价。
若$t$状态可拆成$x,y$两个合法状态,$g[x]+g[y]$也可以用于更新$g[t]$状态。
#include<bits/stdc++.h>
const int maxn = ;
const int maxm = ;
const int INF = 0x3f3f3f3f; struct Edge
{
int y,val;
Edge(int a=, int b=):y(a),val(b) {}
}edges[maxm];
int n,m,d;
bool vis[maxn];
std::queue<int> q;
int f[maxn][],g[];
int edgeTot,head[maxn],nxt[maxm]; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
void spfa(int st)
{
for (int i=; i<=n; i++)
if (f[i][st]!=INF) q.push(i);
while (q.size())
{
int tt = q.front();
q.pop(), vis[tt] = ;
for (int i=head[tt]; i!=-; i=nxt[i])
{
int v = edges[i].y, w = edges[i].val;
if (f[v][st] > f[tt][st]+w){
f[v][st] = f[tt][st]+w;
if (!vis[v]) vis[v] = , q.push(v);
}
}
}
}
bool check(int num)
{
for (int i=; i<d; i++)
if (((num>>i)&)&&((num>>(d+i))&)==) return ;
return ;
}
void addedge(int u, int v)
{
int c = read();
edges[++edgeTot] = Edge(v, c), nxt[edgeTot] = head[u], head[u] = edgeTot;
edges[++edgeTot] = Edge(u, c), nxt[edgeTot] = head[v], head[v] = edgeTot;
}
int main()
{
memset(head, -, sizeof head);
memset(f, 0x3f3f3f3f, sizeof f);
memset(g, 0x3f3f3f3f, sizeof g);
n = read(), m = read(), d = read();
for (int i=; i<=m; i++) addedge(read(), read());
for (int i=; i<=d; i++)
f[i][<<(i-)] = , f[n-i+][<<(d+i-)] = ;
for (int i=; i<<<(d<<); i++)
{
for (int j=; j<=n; j++)
for (int s=i&(i-); s; s=(s-)&i)
f[j][i] = std::min(f[j][i], f[j][s]+f[j][i-s]);
spfa(i);
for (int j=; j<=n; j++) g[i] = std::min(g[i], f[j][i]);
}
for (int i=; i<<<(d<<); i++)
for (int s=i&(i-); s; s=(s-)&i)
if (check(s)&&check(i-s))
g[i] = std::min(g[i], g[s]+g[i-s]);
if (g[(<<(d<<))-] != INF)
printf("%d\n",g[(<<(d<<))-]);
else puts("-1");
return ;
}
END
初涉斯坦纳树&&bzoj4774: 修路的更多相关文章
- 【BZOJ4774】修路(动态规划,斯坦纳树)
[BZOJ4774]修路(动态规划,斯坦纳树) 题面 BZOJ 题解 先讲怎么求解最小斯坦纳树. 先明白什么是斯坦纳树. 斯坦纳树可以认为是最小生成树的一般情况.最小生成树是把所有给定点都要加入到联通 ...
- 【BZOJ4774/4006】修路/[JLOI2015]管道连接 斯坦纳树
[BZOJ4774]修路 Description 村子间的小路年久失修,为了保障村子之间的往来,法珞决定带领大家修路.对于边带权的无向图 G = (V, E),请选择一些边,使得1 <= i & ...
- 【BZOJ4774】修路 [斯坦纳树]
修路 Time Limit: 20 Sec Memory Limit: 256 MB Description Input Output 仅一行一个整数表示答案. Sample Input 5 5 2 ...
- 「长乐集训 2017 Day8」修路 (斯坦纳树)
题目描述 村子间的小路年久失修,为了保障村子之间的往来,AAA君决定带领大家修路. 村子可以看做是一个边带权的无向图GGG, GGG 由 nnn 个点与 mmm 条边组成,图中的点从 1∼n1 \si ...
- 【BZOJ2595】游览计划(状压DP,斯坦纳树)
题意:见题面(我发现自己真是越来越懒了) 有N*M的矩阵,每个格子有一个值a[i,j] 现要求将其中的K个点(称为关键点)用格子连接起来,取(i,j)的费用就是a[i,j] 求K点全部连通的最小花费以 ...
- HDU 4085 斯坦纳树
题目大意: 给定无向图,让前k个点都能到达后k个点(保护地)中的一个,而且前k个点每个需要占据后k个中的一个,相互不冲突 找到实现这个条件达到的选择边的最小总权值 这里很容易看出,最后选到的边不保证整 ...
- 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 ...
- hdu 3311 斯坦纳树
思路:虚拟一个0号节点,将每个点建一条到0号节点的边,权值为挖井需要的价值.并要保证0号节点同另外n个寺庙一样被选择即可. 然后就是求斯坦纳树了. #include<map> #inclu ...
- HDU 3311 Dig The Wells(斯坦纳树)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3311 [题意] 给定k座庙,n个其他点,m条边,点权代表挖井费用,边权代表连边费用,问使得k座庙里 ...
随机推荐
- Luogu P1637 三元上升子序列【权值线段树】By cellur925
题目传送门 emmm..不开结构体的线段树真香! 首先我们知道"三元上升子序列"的个数就是对于序列中的每个数,**它左边比他小的数*它右边比他大的数**.但是如何快速求出这两个数? ...
- vue路由的四种传值
第一种:props 配置: 组件内定义: props: ['id'] 路由映射配置,开启props:true : { path: '/user/:id', component: User, props ...
- 分享| 语义SLAM的未来与思考(泡泡机器人)
相比典型的点云地图,语义地图能够很好的表示出机器人到的地方是什么,机器人“看”到的东西是什么.比如进入到一个房间,点云地图中,机器人并不能识别显示出来的一块块的点云到底是什么,但是语义地图的构建可以分 ...
- edge 浏览器自动识别电话号码解问题解决方法
解决方案:再head中加上: <meta name="format-detection" content="telephone=no">
- HDU-2767-ProvingEquivalences
链接:https://vjudge.net/problem/HDU-2767 题意: 给一个图,求最少需要几条边将其连成一个强连通图 思路: tarjan,缩点,考虑缩点后的图,出度为0的点和入度为0 ...
- HDU1409 Is It a Number
http://acm.hdu.edu.cn/showproblem.php?pid=1409 没啥好说的,至今也不知道到底错在哪里了,看了discuss才过的 #include <iostrea ...
- mysql 驱动问题
转 : https://blog.csdn.net/bloodycuckoo/article/details/51175339 转 : https://blog.csdn.net/u010746431 ...
- [干货分享] AXURE-整套高保真UI框架和元件组(暗黑风格)
写在前面 在我们的开发团队里,一般在产品通过策划和需求评审后,在还没开始设计之前,产品经理和美工会一起定一套UI规范. 一方面用于规范整体界面,防止界面开发过程中出现UI不一致性的情况(有时候标准 ...
- 渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程(下)
关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/08/12/es-code03/ 前提 上篇文章写完了 ES 流程启动的一部分,main 方法都入 ...
- VS2012,更新补丁后的残忍--创建项目未找到与约束匹配的导出
解决方法网址:http://blog.csdn.net/jly4758/article/details/18660945