题目链接 f[i][s]表示以i为根节点,当前关键点的连通状态为s(每个点是否已与i连通)时的最优解.i是枚举得到的根节点,有了根节点就容易DP了. 那么i为根节点时,其状态s的更新为 \(f[i][s]=min\{f[i][s']+f[i][\complement_{s}s']-cost[i]\},s'\in s\)(枚举子集s'后,显然只需要s'的补集.减cost[i]是因为两种状态都包含,cost[i]算重了) 如果我们想合并入当前连通块一个新的非关键点v并以v为根,那么 \(f[v][s…
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2595 [题意] 给定N*M的长方形,选最少权值和的格子使得要求的K个点连通. [科普] “斯坦纳树”就是包含给定点的最小生成树. [思路] 那么本题就是求一棵斯坦纳树. 设f[i][j][S]表示在点(i,j)且与之相连的点的状态为S. 有两种转移: f[i][j][S]<-f[i][j][S’]+f[i][j][S-S’]-a[i][j],合并子集 f[i][j][S]<-f[i…
BZOJ_2595_[Wc2008]游览计划_斯坦纳树 题意: 分析: 斯坦纳树裸题,有几个需要注意的地方 给出矩阵,不用自己建图,但枚举子集转移时会算两遍,需要减去当前点的权值 方案记录比较麻烦,两边的转移都需要记录,最后dfs找方案会比较容易理解 代码: #include <stdio.h> #include <string.h> #include <algorithm> #include <queue> using namespace std; #de…
传送门 题意:略 论文 <SPFA算法的优化及应用> http://www.cnblogs.com/lazycal/p/bzoj-2595.html 本题的核心就是求斯坦纳树: Steiner Tree: Given an undirected graph with non-negative edge weights and a subset of vertices, usually referred to as terminals, the Steiner tree problem in g…
BZOJ2595 Wc2008 游览计划 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个景点: 否则表示控制该方块至少需要的志愿者数目. 相邻的整数用 (若干个) 空格隔开, 行首行末也可能有多余的空格. Output 由 N + 1行组成.第一行为一个整数,表示你所给出的方案中安排的志愿者总数目. 接下来 N行,每行M 个字符,描述方案中相应方块的情况: z ‘_’(下划线)表示该方…
上个月写的题qwq--突然想写篇博客 题目: 洛谷4294 分析: 斯坦纳树模板题. 简单来说,斯坦纳树问题就是给定一张有边权(或点权)的无向图,要求选若干条边使图中一些选定的点连通(可以经过其他点),且边权(或点权)之和最小.很明显,这样最终形成的是一棵树. 通常,斯坦纳树问题规模都比较小.考虑状压DP.用\(dp[u][S]\)表示让点\(u\)与集合\(S\)中所有关键点连通的最小花费.有如下两种转移: 第一,把两条到\(u\)的路径拼在一起,减去重合点\(u\)的点权,即(\(w_u\)…
斯坦纳树板子题. 考虑状压dp,设f[i][j][S]表示当前在点(i,j)考虑转移,其所在的联通块包含的关键点集(至少)为S的答案. 转移时首先枚举子集,有f[i][j][S]=min{f[i][j][x]+f[i][j][y]-a[i][j]} (x&y=0,x|y=S). 然后考虑从点(i,j)从哪拓展而来,有f[i][j][S]=min{f[x][y][S]}+a[i][j],其中(x,y)为(i,j)的相邻点,使用spfa转移. 这里第二种转移仅在相同关键点集下进行,因为由更小点集转移…
[Luogu4294] 题解 : 斯坦纳树 \(dp[i][j]\) 表示以\(i\)号节点为根,当前状态为\(j\)(与\(i\)连通的点为\(1\)) 当根\(i\)不改变时状态转移方程是: \(dp[i][j] = \min_{s \in j}\{dp[i][s] + dp[i][\complement_js] - val[i]\}\) 当根改变时,要求\(i,k\)相邻 : \(dp[i][j] = \min\{dp[k][j] + val[i]\}\) 记录\(pre[i][now]\…
[题目分析] 斯坦纳树=子集DP+SPFA? 用来学习斯坦纳树的模板. 大概就是用二进制来表示树包含的点,然后用跟几点表示树的形态. 更新分为两种,一种是合并两个子集,一种是换根,换根用SPFA迭代即可. [代码] #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <set> #include <map> #include…
Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个景点:否则表示控制该方块至少需要的志愿者数目. 相邻的整数用 (若干个) 空格隔开,行首行末也可能有多余的空格. Output 由 N + 1行组成.第一行为一个整数,表示你所给出的方案中安排的志愿者总数目. 接下来 N行,每行M 个字符,描述方案中相应方块的情况: z  ‘_’(下划线)表示该方块没有安排志愿者: z  ‘o’(小写英文字…