【NOIP2017】宝藏
题目描述
参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 \(n\) 个深埋在地下的宝藏屋, 也给出了这 \(n\) 个宝藏屋之间可供开发的 \(m\) 条道路和它们的长度。
小明决心亲自前往挖掘所有宝藏屋中的宝藏。但是,每个宝藏屋距离地面都很远, 也就是说,从地面打通一条到某个宝藏屋的道路是很困难的,而开发宝藏屋之间的道路 则相对容易很多。
小明的决心感动了考古挖掘的赞助商,赞助商决定免费赞助他打通一条从地面到某 个宝藏屋的通道,通往哪个宝藏屋则由小明来决定。
在此基础上,小明还需要考虑如何开凿宝藏屋之间的道路。已经开凿出的道路可以 任意通行不消耗代价。每开凿出一条新道路,小明就会与考古队一起挖掘出由该条道路 所能到达的宝藏屋的宝藏。另外,小明不想开发无用道路,即两个已经被挖掘过的宝藏 屋之间的道路无需再开发。
新开发一条道路的代价是:
\]
\(L\)代表这条道路的长度,\(K\)代表从赞助商帮你打通的宝藏屋到这条道路起点的宝藏屋所经过的 宝藏屋的数量(包括赞助商帮你打通的宝藏屋和这条道路起点的宝藏屋) 。
请你编写程序为小明选定由赞助商打通的宝藏屋和之后开凿的道路,使得工程总代 价最小,并输出这个最小值。
输入输出格式
输入格式
第一行两个用空格分离的正整数 \(n\),\(m\),代表宝藏屋的个数和道路数。
接下来 \(m\) 行,每行三个用空格分离的正整数,分别是由一条道路连接的两个宝藏 屋的编号(编号为 \(1\sim n\)),和这条道路的长度 \(v\)。
输出格式
一个正整数,表示最小的总代价。
数据范围
对于 \(20\%\)的数据: 保证输入是一棵树,\(1 \le n \le 8\),\(v \le 500\)且所有的 \(v\) 都相等。
对于 \(40\%\)的数据: \(1 \le n \le 8\),\(0 \le m \le 1000\),\(v \le 5000\)且所有的 \(v\) 都相等。
对于 \(70\%\)的数据: \(1 \le n \le 8\) ,\(0 \le m \le 1000\),\(v \le 5000\)。
对于 \(100\%\)的数据:\(1 \le n \le 12\), \(0 \le m \le 1000\),\(v \le 500000\)。
题解
看题第一眼,Prime,但是发现Prime是错的,Prime的贪心准则不符合这道题,看一眼数据范围\(1 \le n \le 12\),我们可以用状态压缩,\(f[i][j]\)表示当前已探索的点集为i上一层的点集为j,这样的状态转移就十分简单了,但是,如果仅仅是这样,我们是过不了\(100\%\)的数据的,我们来想办法压一下维,我们考虑一下能否把第二维压去,但是,我们会发现,这样的话,对于在集合\(i\)中的点,我们就没有办法直接判定它是在那一层中的。所以我们每次转移时还需要枚举上一层的状态。
代码
#include<bits/stdc++.h>
using namespace std;
long long dist[15][15];
struct Data{
long long sum;
int dist[15];
}dp[1 << 13];
long long inf, ans = 0x7ffffffff;
int main()
{
memset(dist, 0x7f, sizeof(dist));
inf = dist[0][0];
int n, m, x, y;
long long w;
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; ++ i)
{
scanf("%d%d%lld", &x, &y, &w);
dist[x][y] = dist[y][x] = min(dist[x][y], w);
}
int U = (1 << n) - 1;
for(int root = 1; root <= n; ++ root)
{
memset(dp, 0x3f, sizeof(dp));
dp[1 << (root - 1)].dist[root] = 1, dp[1 << (root - 1)].sum = 0;
for(int i = 0; i <= U; ++ i)
{
int S = i | (1 << (root - 1));
for(int u = 1; u <= n; ++ u)
if((S & (1 << (u - 1))))
for(int v = 1; v <= n; ++ v)
if((dist[u][v] != inf) && (!(S & (1 << (v - 1)))))
if(dp[S | (1 << (v - 1))].sum > dp[S].sum + dist[u][v] * ((long long)dp[S].dist[u]))
{
dp[S | (1 << (v - 1))] = dp[S];
dp[S | (1 << (v - 1))].sum = dp[S].sum + dist[u][v] * ((long long)dp[S].dist[u]);
dp[S | (1 << (v - 1))].dist[v] = dp[S | (1 << (v - 1))].dist[u] + 1;
}
}
ans = min(ans, dp[U].sum);
}
printf("%lld\n", ans);
}
【NOIP2017】宝藏的更多相关文章
- 【比赛】NOIP2017 宝藏
这道题考试的时候就骗了部分分.其实一眼看过去,n范围12,就知道是状压,但是不知道怎么状压,想了5分钟想不出来就枪毙了状压,与AC再见了. 现在写的是状压搜索,其实算是哈希搜索,感觉状压DP理解不了啊 ...
- [NOIP2017]宝藏 状压DP
[NOIP2017]宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖 ...
- [NOIP2017]宝藏 子集DP
题面:[NOIP2017]宝藏 题面: 首先我们观察到,如果直接DP,因为每次转移的代价受上一个状态到底选了哪些边的影响,因此无法直接转移. 所以我们考虑分层DP,即每次强制现在加入的点的距离为k(可 ...
- NOIP2017宝藏 [搜索/状压dp]
NOIP2017 宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘 ...
- NOIP2017 - 宝藏
LibreOJ链接 Description 给出一个\(n(n\leq12)\)个点\(m(m\leq1000)\)条边的带权无向图,求该图的一棵生成树,使得其边权×该边距根的深度之和最小. Solu ...
- Luogu 3959 [NOIP2017] 宝藏
NOIP2017最后一道题 挺难想的状压dp. 受到深度的条件限制,所以一般的状态设计带有后效性,这时候考虑把深度作为一维,这样子可以保证所有状态不重复计算一遍. 神仙预处理:先处理出一个点连到一个集 ...
- 洛谷P3959 [NOIP2017]宝藏
[题目描述] 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋,也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中的宝藏.但 ...
- NOIP2017 宝藏 题解报告【状压dp】
题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中的宝藏.但是 ...
- 【洛谷P3959】[NOIP2017] 宝藏
宝藏 题目链接 首先,打了一个prim,得了45分 #include<iostream> #include<cstring> #include<cstdio> #i ...
- [NOIP2017] 宝藏 【树形DP】【状压DP】
题目分析: 这个做法不是最优的,想找最优解请关闭这篇博客. 首先容易想到用$f[i][S][j]$表示点$i$为根,考虑$S$这些点,$i$的深度为$j$情况的答案. 转移如下: $f[i][S][j ...
随机推荐
- 九: 操作提示(js版本)
一.toast 消息提示框 他用到了一个wx.showToast(object) 这样一个方法.作用是显示提示框. /* ---page/test/test.wxml----*/ <butt ...
- Java新人拿到一台新的电脑需要装配什么
适用对象:新手 装备:win10 一.IDEA 插件等 说明 其他 TranslationPlugin 翻译插件 GitHub地址 MyBatis-Generator 自动生成Mybatis文件 Al ...
- DevExpress13.2.9 控件使用经验总结
一.换肤功能 1. 添加 DevExpress.OfficeSkins 和 DevExpress.BonusSkins 两个引用 2. 皮肤注册 DevExpress.UserSkins.BonusS ...
- MapReduce学习
参考文章 参考文章2 shuffle的过程分析 Hadoop学习笔记:MapReduce框架详解 谈mapreduce运行机制,可以从很多不同的角度来描述,比如说从mapreduce运行流程来讲解,也 ...
- Android学习笔记(3)----手机调试[OFFLINE]的解决方式
问题描述 今天用Android Studio开发了一个简单的调用摄像头的App,结果想调试的时候发现选择调试设备的对话框中,手机名称后面总是跟着一个[OFFLINE]的标识,只能选择启动AVD来进行调 ...
- cacti 安装与 与不能显示图像故障解决方案
on debian 7&8 apt-get install snmp snmpd apt-get install cacti cacti-spine apt-get install moreu ...
- RocketMQ读书笔记6——可靠性优先的使用场景
[顺序消息] 顺序消费是指消息的产生顺序和消费顺序相同. 比如订单的生成.付款.发货,这三个消息必须按顺序处理才可以. [顺序消息的分类] 全局顺序消息和部分顺序消息. 上面订单的例子,其实是部分顺序 ...
- 瞥了一眼js
JS打开超链接的几种形式1.window.open(''url'') 2.用自定义函数<script>function openWin(tag,obj){obj.target=" ...
- How to safely downgrade or remove glibc with yum and rpm
Environment Red Hat Enterprise Linux 5 Red Hat Enterprise Linux 6 glibc, glibc-common, glibc-devel, ...
- 个人总结4-dbutils总结
昨天学习了dbutils的使用方法,简化了使用的步骤,可以使用三四步就可以写出来,queryRunner的使用方法有了简单的了解,目前可以使用dbutils实现最简单的增删改查. 今天准备学习准备写登 ...