LGOJP3959 宝藏
题目链接
题解
一开始想了一个错误的状压dp,水了40分。
这里先记录一下错误的做法:
错解:
设\(g[i,j,S]\)从\(i\)到\(j\),只经过集合\(S\)中的点的最短路,这个可以\(O(n^3 2 ^ n)\)处理出来。
设\(f[S]\)表示生成树的集合为\(S\)时的最小代价,每次枚举起点,以及新加入生成树的点,利用\(g\)数组可以\(O(1)\)算出来\(K\)。总复杂度是\(O(n^3 2^n)\)
那么为什么错了呢?因为\(g[i,j,S]\)是一个点集内互达的点的\(\min\),其涉及到的边集远大于生成树的边集,所以相当于利用了很多没有选的边来减少\(K\),所以算出来的\(K\)是错误的。
正解:
设\(g[S]\)表示从集合\(S\)内的点出发,只走一条边可到达的点集(包括集合\(S\)内的点)。这个可以\(O(n^2 2^n)\)处理。
设\(f[i,S]\)为生成树最大树高为\(i\),目前生成树集合为\(S\)的最小代价。
我们枚举\(S\)的子集\(S0\),设其在\(S\)为全集时的补集为\(S1\),那么当\(g[S0]|S=g[S0]\)时(即通过\(S0\)的中的点可以到达当前集合\(S\)中全部的点),\(f[i][S]=\min\{f[i-1][S0]+cost \}\)。\(cost\)即为将\(S1\)与\(S0\)合并为\(S\)的最小代价。
这里有一个很重要的结论,在最优解中,拓展的集合\(S1\)在\(S\)中树高均为\(i\)(\(S0\)中最大树高为\(i-1\))。
考虑证明,假设有一个点\(x(x\in S0)\),有边\(d[y][x]>d[z][x],dep_y<dep_z\),满足\(d[y][x]*(dep_y+1)<d[z][x]*(dep_z+1)\)。
那在当\(y\)为生成树集中的最深点时一定已经拓展到了点\(x\),所以一定有另一状态\(S_2\)可以转移到\(S\)使答案最优。
即最优解中的生成树一定可以按深度拓展。
所以转移时的\(cost\)只需枚举\(S_1\)中的点,求出\(S_1\)到\(S_0\)中的点的\(\min_{dis}\)之和,乘上\(i\),就是这次加边的\(cost\)。
初始化\(f[2^k]=0(k\in [0,n-1])\)。答案即为所有集合\(S\)为全集时的\(f\)值的\(\min\)。
不看题解还是不会写...
因为状压枚举子集的复杂度是\(O(3^n)\)。所以总复杂度是\(O(n^2 3 ^n)\)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 13;
const int inf = 0x3f3f3f3f;
int n, m, w[N][N];
int f[N][(1<<N)+10], g[(1<<N)+10];
int main() {
memset(w, 0x3f, sizeof(w));
cin >> n >> m;
for(int u, v, k, i = 1; i <= m; ++i) {
cin >> u >> v >> k;
--u; --v;
w[u][v] = w[v][u] = min(w[u][v], k);
}
for(int S = 1; S < 1 << n; ++S)
for(int i = 0; i < n; ++i)
if((S >> i) & 1) {
w[i][i] = 0; g[S] |= 1 << i;
for(int j = 0; j < n; ++j)
if(w[i][j] != inf) g[S] |= 1 << j;
}
memset(f, 0x3f, sizeof(f));
for(int i = 0; i < n; ++i) f[0][1 << i] = 0;
for(int S = 1; S < 1 << n; ++S) {
for(int S0 = S - 1; S0; S0 = (S0 - 1) & S) {
int S1 = S ^ S0;
int sum = 0;
if((g[S0] | S) == g[S0]) {
for(int i = 0; i < n; ++i) {
if((S1 >> i) & 1) {
int tmp = inf;
for(int j = 0; j < n; ++j) {
if(((S0 >> j) & 1))
tmp = min(tmp, w[i][j]);
}
sum += tmp;
}
}
for(int i = 1; i < n; ++i) { // 树高
if(f[i - 1][S0] != inf)
f[i][S] = min(f[i][S], f[i - 1][S0] + i * sum);
}
}
}
}
int ans = inf;
for(int i = 0; i < n; ++i) ans = min(ans, f[i][(1 << n) - 1]);
printf("%d\n", ans);
}
LGOJP3959 宝藏的更多相关文章
- 算法:poj1066 宝藏猎人问题。
package practice; import java.util.Scanner; public class TreasureHunt { public static void main(Stri ...
- 【BZOJ-1924】所驼门王的宝藏 Tarjan缩点(+拓扑排序) + 拓扑图DP
1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 787 Solved: 318[Submit][Stat ...
- zzulioj 1907小火山的宝藏交易(dfs记忆化搜索)
#include <stdio.h> #include <algorithm> #include <string.h> #include <vector> ...
- codevs3196 黄金宝藏
题目描述 Description 小毛终于到达宝藏点,他意外地发现有一个外星人(名叫Pluto).宝藏是一些太空黄金,有n堆排成一行,每堆中有xi颗黄金.小毛和Pluto决定轮流从中取出黄金,规则是每 ...
- bzoj 1924 [Sdoi2010]所驼门王的宝藏(构图,SCC,DP)
Description Input 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室 ...
- (zzuli)1907 小火山的宝藏收益
Description 进去宝藏后, 小火山发现宝藏有N个房间,且这n个房间通过N-1道门联通. 每一个房间都有一个价值为Ai的宝藏, 但是每一个房间也都存在一个机关.如果小火山取走了这个房间的宝藏, ...
- zzuli 1907: 小火山的宝藏收益 邻接表+DFS
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 113 Solved: 24 SubmitStatusWeb Board Description ...
- [SDOI2010]所驼门王的宝藏
题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...
- [51nod1474]宝藏图
有n堆宝藏,每一堆宝藏有一个挖掘所需要的时间ti,有一个价值qi. 现在是做一个宝藏图.这个宝藏图是这样的,宝藏图的形状是一棵二叉树,二叉树刚好有k个叶子结点,从n堆宝藏中选k堆放到二叉树的叶子结点上 ...
随机推荐
- leetcode刷题系列(一) 26题 删除排序数组中的重复项
题干 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示 ...
- Linux用户查询、新增&删除
1.查询用户tail -1 /etc/passwd 2.新增用户&用户组groupadd testgroup #组的添加useradd testuser #创建用户testuserpasswd ...
- 绘制UML图的工具
目前在用processOn网站进行绘制:https://www.processon.com/ 学习其简单的入门教程: https://www.processon.com/support https:/ ...
- 【Codeforces627E】Orchestra(双指针_链表)
题目 Codeforces627E 翻译 好久没做英语阅读了,来爽一爽吧 ~ 描述 保罗是管弦乐队的成员.弦乐组安排在一个 \(r\times c\) 的矩形方格区域中,其中有 \(n\) 个中提琴手 ...
- Oracle RAC 创建实例出错(非+DATA目录)的简单处理
今天进行oracle的rac测试 发现开发同事没有写好 oracle rac的设置. 创建完之后就会报错了 因为自己对oracle 的RAC 不太熟悉 不太会用.. 所以用 一个比较简单的办法. a ...
- Python爬虫:现学现用xpath爬取豆瓣音乐
爬虫的抓取方式有好几种,正则表达式,Lxml(xpath)与BeautifulSoup,我在网上查了一下资料,了解到三者之间的使用难度与性能 三种爬虫方式的对比. 这样一比较我我选择了Lxml(xpa ...
- git 学习笔记 --- Rebase
在上一节我们看到了,多人在同一个分支上协作时,很容易出现冲突.即使没有冲突,后push的童鞋不得不先pull,在本地合并,然后才能push成功. 每次合并再push后,分支变成了这样: $ git l ...
- easyUi——datetimebox绑定数据失效
在做easy-ui时候,绑定数据不管在怎么写,都绑定不上去,最后发现是因为 标签的ID没有写,尴尬了,记录一下,防止后期出错. ui代码 <script type="text/java ...
- C#泛型集合之——字典
字典基础 1.概述:字典是一组映射,更准确的说应该是一个函数.因为它的键值不能重复,而值可以重复.其逻辑实质也是顺序型的 2.操作: (1)创建: Dictionary<键类型,值类型> ...
- python 4. path的定义及参数,re_path
path定义 path函数的定义为:path(route,view,name=None,kwargs=None) 可以查看官方文档 → 官方文档,下面是取自官方文档关于path的参数 函数 path( ...