参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 \(n\) 个深埋在地下的宝藏屋, 也给出了这 \(n\) 个宝藏屋之间可供开发的 \(m\) 条道路和它们的长度。

小明决心亲自前往挖掘所有宝藏屋中的宝藏。但是,每个宝藏屋距离地面都很远, 也就是说,从地面打通一条到某个宝藏屋的道路是很困难的,而开发宝藏屋之间的道路 则相对容易很多。

小明的决心感动了考古挖掘的赞助商,赞助商决定免费赞助他打通一条从地面到某 个宝藏屋的通道,通往哪个宝藏屋则由小明来决定。

在此基础上,小明还需要考虑如何开凿宝藏屋之间的道路。已经开凿出的道路可以 任意通行不消耗代价。每开凿出一条新道路,小明就会与考古队一起挖掘出由该条道路 所能到达的宝藏屋的宝藏。另外,小明不想开发无用道路,即两个已经被挖掘过的宝藏 屋之间的道路无需再开发。

新开发一条道路的代价是:

\(\mathrm{L} \times \mathrm{K}\)

\(L\)代表这条道路的长度,\(K\)代表从赞助商帮你打通的宝藏屋到这条道路起点的宝藏屋所经过的 宝藏屋的数量(包括赞助商帮你打通的宝藏屋和这条道路起点的宝藏屋) 。

请你编写程序为小明选定由赞助商打通的宝藏屋和之后开凿的道路,使得工程总代 价最小,并输出这个最小值。

输入格式

第一行两个用空格分离的正整数 \(n,m\),代表宝藏屋的个数和道路数。

接下来 \(m\) 行,每行三个用空格分离的正整数,分别是由一条道路连接的两个宝藏 屋的编号(编号为 \(1-n\)),和这条道路的长度 \(v\)。

输出格式

一个正整数,表示最小的总代价。

【数据规模与约定】

对于 \(\%20\)的数据: 保证输入是一棵树,\(1 \le n \le 8\),\(v \le 5000\) 且所有的 \(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\)

SOLUTION

好吧其实这题还是有点难的,蒟蒻我当时还是在考场上拿到这题一脸懵逼。

看到这题的规模,\(n \le 12\),一般就会有几种想法:爆搜,状压(还有大佬写的模拟退火。。。是本弱弱不会的了) 。

由题意可得,我们求完之后会是一棵树,图上找一棵树。

首先,我们想到某一个点\(i\) 作为这个图中树的根,对于其他点,我们关心其他点到起点的距离。

对于第一部分分,我们只需要对每一个根做一次树形DP即可。

之后变成了一个图,我们考虑状态压缩。

我们记 \(f[S][i]\) , 表示我们对于状态为 \(S\) 的点集,最深层数为 \(i\) 。

然后我们可以稍微思考一下,对于点集 \(S\) ,他可以由自己的子点集 \(S1\) 转移而来, ,于是,我们就有:

\(f[S][d] = min{f[S1][d-1] + (d-1) \times transfer[S1][S]}, S1\subset S\)

解释一下,这个式子相当于就是把\(S1\) 中的点,向外扩展一层,扩展完点集为\(S\)。

\(transfer[S1][S]\) 表示从 \(S1\)到 \(S\) 的最小价值。

我们考虑S中点\(i\), 不在\(S1\) 中, 那么从\(i\) 转移到\(S1\) 的最小价值为:

\(W[i][S1] = min(e[i][j]), j \in S1\)

但是事实上这个W数组是不用写出来的,一次次加上去就好了。

然后

\(transfer[S1][S] = \sigma W[i][S1] ,i\in S, i\notin S1\)

但是吧,不知道大家有没有这个困惑

我们压根没考虑根节点!!

在我写完时候也有点纠结(纠结了好久,写完才想到)

其实我们考虑一个点

我不会画画(偷懒),引用了大佬的博客GoldenPotato的OI世界

考虑这个图里,我们以图中给的为根,如果我们统计k=1时候没有加最右边的一个点,到k=2的状态时把这个点算进去,那不是距离根节点只有一个宝藏屋的边要\(\times 2\)

显然是不对的。

但是我们可以在其他点为根的状态中,把这个点加进去,就一定会有最优的解。

所以我们的答案统计为: \(ans = min{f[i][(1<<n)-1], i \in [1,n]}\)

还有一个小技巧,就是枚举子集,

	for(int s1=s; s1; s1=(s1-1)&s)

复杂度这样就从\(n^2\times 4^n\) 降到 \(n^2 \times 3^n\)

于是乎,贴代码。

如果我哪里有疏漏,欢迎大家指正~

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define _(d) while(d(isdigit(ch=getchar())))
template <class T> void g(T&t){T x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch-48;_()x=x*10+ch-48;t=f*x;}
typedef long long ll;
const int N=14;
int n, m, inf, tr[1<<N][1<<N], e[N][N];ll f[N][1<<N];
int main(){
g(n), g(m);
memset(e, 63, sizeof(e)); inf = e[0][0];
rep(i,1,m){
int x, y, z; g(x), g(y), g(z);
e[x][y] = e[y][x] = min( e[x][y], z );
} rep(s, 0, (1<<n)-1){
for(int s1=s; s1; s1=(s1-1)&s){
int tmp= s ^ s1;
bool flag=0;
rep(i, 1, n){
if( 1<<(i-1) & tmp ){
int tt= inf;
rep(j, 1, n){
if( 1<<(j-1) & s1){
tt= min( tt, e[i][j] );
}
}
if( tt == inf ){
flag = 1;
break;
}
tr[s1][s] += tt;
}
}
if( flag ){
tr[s1][s] = inf;
}
}
} memset(f, 63, sizeof(f));
ll ans=f[0][0];
rep(i, 1, n) f[1][1<<(i-1)] = 0;
rep(i, 2, n){
rep( s, 0, (1<<n)-1 )
for(int s1=s; s1; s1=(s1-1) & s ){
if(tr[s1][s]!=inf)
f[i][s]=min(f[i][s], f[i-1][s1] + tr[s1][s]*(i-1) ); }
}
rep(i, 1, n) ans=min(ans, f[i][(1<<n)-1]);
printf("%lld\n",ans);
return 0;
}

水题挑战3: NOIP 2017 宝藏的更多相关文章

  1. 水题挑战4: luogu P1280 尼克的任务

    题目描述 尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮件包含了尼克主管的部门当天要完成的全部任务,每个任务由一个开始时刻与一个持续时间构成. 尼克的一个工作日为 \(n\) 分钟,从 ...

  2. 水题挑战1:NOIP 2013 选择客栈

    丽江河边有\(n\) 家很有特色的客栈,客栈按照其位置顺序从 \(1\) 到 \(n\) 编号.每家客栈都按照某一种色调进行装饰(总共 \(k\) 种,用整数 \(0 \sim k-1\) 表示),且 ...

  3. 水题挑战2 :NOIP提高组 2011 聪明的质监员

    小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 \(n\) 个矿石,从\(1\) 到 \(n\) 逐一编号,每个矿石都有自己的重量 \(w_i\) 以及价值 \(v_i\) .检验矿 ...

  4. [NOIp 2017]宝藏

    Description 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋 ...

  5. NOIP 2017 宝藏 - 动态规划

    题目传送门 传送门 题目大意 (家喻户晓的题目不需要题目大意) 设$f_{d, s}$表示当前树的深度为$d$,与第一个打通的点连通的点集为$s$. 每次转移的时候不考虑实际的深度,深度都当做$d$, ...

  6. 水题挑战6: CF1444A DIvision

    A. Division time limit per test1 second memory limit per test512 megabytes inputstandard input outpu ...

  7. World Finals 2017 (水题题解)

    看大佬做2017-WF,我这种菜鸡,只能刷刷水题,勉强维持生活. 赛后补补水题. 题目pdf链接,中文的,tls翻译的,链接在这里 个人喜欢在vjudge上面刷题. E Need for Speed ...

  8. 历年真题 未完成(Noip 2008 - Noip 2017)

    Noip 2008 :全部 Noip 2009 :全部 Noip 2010 :AK Noip 2011 :AK Noip 2012 : Vigenère 密码,国王游戏,开车旅行 Noip 2013 ...

  9. CODE FESTIVAL 2017 qual B B - Problem Set【水题,stl map】

    CODE FESTIVAL 2017 qual B B - Problem Set 确实水题,但当时没想到map,用sort后逐个比较解决的,感觉麻烦些,虽然效率高很多.map确实好写点. 用map: ...

随机推荐

  1. Python-通过twisted实现数据库异步插入?

    如何通过twisted实现数据库异步插入? 1. 导入adbapi 2. 生成数据库连接池 3. 执行数据数据库插入操作 4. 打印错误信息,并排错 #!/usr/bin/python3 __auth ...

  2. P2590 树的统计

    一道树剖的模板题 首先,由于本人比较懒,就把单点修改写成了区间修改,其实也没有有多大区别(关键是我不会写单点修改QAQ) 不得不说,树剖的码量比较大,调了一上午才勉强调完. 这道题要求我们支持 单点修 ...

  3. vue中,使用 es6的 ` 符号给字符串之间换行

    我这里分功能是点击"复制范围",就相当于复制图上的坐标点一样的数据和格式: "复制功能"的代码如下: copyPoints() { const vm = thi ...

  4. 部署MongoDB-4.2.7

    二进制部署很简单 创建存放软件目录下载解压 存放数据和日志及配置文件路径需要手工进行创建 mkdir -p /application/tools/ cd /application/tools/ wge ...

  5. Varnish 不重启使之配置生效的方法

    Varnish 在内存模式下比较高效,不过它有一个缺点就是 缓存是放在内存里的,一旦重启, 缓存文件也就没了. 往往由于需要调整 vcl 配置文件,但是又不想重启varnish服务,就让配置文件生效的 ...

  6. 项目使用eslint

    今天eslint版本更新了,然后昂,有些奇奇怪怪的错误提示了,然后想,这我得 1.配置一个保存时根据eslint规则自动修复 2.欸,之前编码遇到未使用的变量都会有标记黄线,我很好定位,这会怎么没了 ...

  7. ansible-playbook简介

    1. ansible-playbook简介 • Playbooks 与 adhoc 相比,是一种完全不同的运用 ansible 的方式,是非常之强大的. • 简单来说,playbooks 是一种简单的 ...

  8. 经验分享:Windows10值得推荐的软件,总有一款是你的菜

    今天在知乎上看到有人分享wids10推荐好用的软件:今天小编做了一点点的修改和根据自己的使用情况总结出来转发分享给大家:   1.安全放病毒--火绒[推荐] 2.办公软件--office2019[推荐 ...

  9. linux(centos8):prometheus使用mtail监控错误日志

    一,mtail的用途? mtail :从应用程序日志中提取指标以导出到时间序列数据库或时间序列计算器 它是一个google开发的日志提取工具,用途就是: 实时读取应用程序的日志. 再通过自己编写的脚本 ...

  10. FreeRTOS链表实现

    直接上源码分析 void vListInitialise( List_t * const pxList ){ pxList->pxIndex = ( ListItem_t * ) &( ...