通向地底的传送门

题目描述

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

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

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

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

新开发一条道路的代价是 \(L×K\)

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

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

输入输出格式

输入格式:

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

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

输出格式:

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

输入输出样例

输入样例#1:

4 5
1 2 1
1 3 3
1 4 1
2 3 4
3 4 1

输出样例#1:

4

输入样例#2:

4 5
1 2 1
1 3 3
1 4 1
2 3 4
3 4 2  

输出样例#2:

5

数据规模与约定

对于 $ 20% $ 的数据: 保证输入是一棵树,\(1≤n≤8\) , \(v≤5000\) , 且所有的 \(v\) 都相等。

对于 $ 40% $ 的数据: \(1≤n≤8\) ,\(0≤m≤1000\) ,\(v≤5000\) 且所有的 \(v\) 都相等。

对于 $ 70% $ 的数据: \(1≤n≤8\) ,\(0≤m≤1000\) ,\(v≤5000\)

对于 $ 100% $ 的数据: \(1≤n≤12\) ,\(0≤m≤1000\) ,\(v≤500000\)

思路

显然这道题可以用模拟退火做,当然这篇题解存在的意义绝不是为了对这个毒瘤算法进行讲解,想要了解更多相关信息的读者可以自行脑补右转自家搜索引擎。

首先看数据范围,\(1≤n≤12\),如此之小大家的第一反应应该都是状压\(DP\)吧。再根据题意,我们不难对这个又臭又长混淆视听的题面进行简化:

  • 给定一个 \(N\) 个点 \(M\) 条边的无向图,要求在图中找出一颗生成树,满足树上的节点到根节点的深度 \(d\) 与该点连到树中的边的权值 \(w\) 之积的和最小。

对于选定节点的每一种局面,我们用一个二进制数进行记录,其每一位上的 \(1\) 表示该点已被选中,反之则没被选中。使用数组 \(f[i]\) 记录当前局面下得最小代价。

显然地,对于每一个可能的根节点 \(root\) ,有:

    f[1 << (root - 1)] = 0;

表示初始状态下代价为0。

    f[(1 << n) - 1];

表示我们要求的目标代价。

由于数据范围很小,我们枚举每个点作为根节点计算 \(f\) 数组,再不断对答案进行更新即可。

代码实现上,我们使用深度优先搜索遍历状态空间,对于每一个状态 \(state\) ,摘出其中选定的点(位运算的相关操作稍后会进行补充),遍历该点的所有出边,维护一个记录当前点到选定根节点的 \(dis\) 数组,一旦得到当前状态的更优方案,就对 \(f\) 数组进行更新,如此往复直到所有状态都被更新完毕为止。

值得注意的是,由于每次枚举根节点都相当于对答案数组重新进行计算,所以务必不要忘记对各个变量进行初始化工作。以及,由于给定的数据范围中点数极少而边数相当的多,在图的储存过程中要注意可能出现的重边情况,此时取长度较短的边保留即可。

AC代码

#include<iostream>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<queue>
using namespace std;
int read(){int re = 0,ch = getchar();while(!isdigit(ch))ch = getchar();while(isdigit(ch))re = (re<<1) + (re<<3) + ch - '0',ch = getchar();return re;
}
int g[13][13],dis[13],f[1<<13];
int n,m,ans = 0x3f3f3f3f;
void dfs(int state){for(int i = 1;i <= n;i++){if(!((1<<(i-1))&state)) continue;//排除不是点集中的边for(int j = 1;j <= n;j++){if(g[i][j] == 0x3f3f3f3f || j == i) continue;//遍历出边if(f[state|(1<<j-1)] > f[state] + g[i][j] * dis[i]){//若可以更新f数组int tmp = dis[j];dis[j] = dis[i] + 1;f[state|(1<<(j-1))] = f[state] + g[i][j] * dis[i];dfs(state|(1<<(j-1)));//对新的状态进行递归搜索dis[j] = tmp;//回溯}}}
}
int main(){n = read(),m = read();int u,v,w;memset(g,0x3f,sizeof(g));for(int i = 1;i <= m;i++){u = read(),v = read(),w = read();g[u][v] = min(g[u][v],w);g[v][u] = min(g[v][u],w);//存图与重边处理}for(int i = 1;i <= n;i++){memset(dis,0x3f,sizeof(dis));memset(f,0x3f,sizeof(f));dis[i] = 1;f[1<<(i-1)] = 0;//初始化dfs(1<<(i-1));ans = min(ans,f[(1<<n)-1]);//更新答案}cout << ans;return 0;
} 

转载于:https://www.cnblogs.com/mysterious-garden/p/9757933.html

洛谷 P3959 [NOIP2017]宝藏 题解相关推荐

  1. 信息学奥赛一本通 1414:【17NOIP普及组】成绩 | 洛谷 P3954 [NOIP2017 普及组] 成绩

    [题目链接] ybt 1414:[17NOIP普及组]成绩 洛谷 P3954 [NOIP2017 普及组] 成绩 [题目考点] 1. 算术表达式 2. 自动类型转换 低精度类型与高精度类型计算结果是高 ...

  2. 信息学奥赛一本通 1415:【17NOIP普及组】图书管理员 | 洛谷 P3955 [NOIP2017 普及组] 图书管理员

    [题目链接] ybt 1415:[17NOIP普及组]图书管理员 洛谷 P3955 [NOIP2017 普及组] 图书管理员 [题目考点] 1. 枚举 2. 二分 [解题思路] 解法1:枚举 对于每个 ...

  3. 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)

    洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...

  4. 洛谷P2312 解方程题解

    洛谷P2312 解方程题解 题目描述 已知多项式方程: \[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\] 求这个方程在 \([1,m]\) 内的整数解(\(n\) 和 \(m\) ...

  5. 洛谷P1273 有线电视网 题解

    洛谷P1273 有线电视网 题解 题目链接:P1273 有线电视网 题意: 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为 ...

  6. 洛谷P4568 [JLOI2011] 飞行路线 题解

    洛谷P4568 [JLOI2011] 飞行路线 题解 题目链接:P4568 [JLOI2011] 飞行路线 题意: Alice 和 Bob 现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公 ...

  7. 洛谷P3426 [POI2005]SZA-Template 题解

    洛谷P3426 [POI2005]SZA-Template 题解 题目链接:P3426 [POI2005]SZA-Template 题意:你打算在纸上印一串字母. 为了完成这项工作,你决定刻一个印章. ...

  8. 洛谷P1156 垃圾陷阱 题解浅谈刷表法与填表法

    洛谷P1156 垃圾陷阱 题解&浅谈刷表法与填表法 填表法 :就是一般的动态规划,当前点的状态,可以直接用状态方程,根据之前点的状态推导出来. 刷表法:由当前点的状态,更新其他点的状态.需要注 ...

  9. 洛谷P1262 间谍网络题解

    洛谷P1262 间谍网络题解 题目大意 题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果 A 间谍手中掌握着关于 B 间谍的犯罪证据,则称 A 可以揭发 B.有些间谍收受贿赂,只要 ...

最新文章

  1. JavaScript中的数组与伪数组的区别
  2. linux下ssh登录PIX防火墙
  3. 【数字信号处理】线性常系数差分方程 ( 根据 “ 线性常系数差分方程 “ 与 “ 边界条件 “ 确定系统是否是 “ 线性时不变系统 “ 案例二 | 修改边界条件 | 使用递推方法证明 )
  4. leetcode844. 比较含退格的字符串(栈+双指针)
  5. leetcode —— 863. 二叉树中所有距离为 K 的结点
  6. oracle级联更新与级联删除
  7. 【HASH】【UVA 10125】 Sumset
  8. 网络对抗技术实验二,第一部分,第二部分
  9. 联合主键使用in和not in
  10. 使用VUE分分钟写一个验证码输入组件
  11. C语言学习编程软件推荐
  12. Unity制作3d生存游戏视频教程
  13. Java开发必须掌握!java面试没问技术问题
  14. Linux下载神器XDM,代替IDM
  15. 开利网络拜访普恺图酒业总部,品高端酒,探共赢合作方案
  16. 爸爸给女儿存了一份养老险,女儿50多岁时可以领取30多万
  17. VM虚拟机ssh免密登录其他主机
  18. LVGL V0.01版本移植到STM32F4
  19. SaaS、PaaS、IaaS、DaaS、BaaS简介
  20. P****cms简单去版权,不逆向dll,只是简单的隐藏掉而已

热门文章

  1. java jdk使用教程_Java基础教程——安装JDK
  2. 破碎的项链 Broken Necklace
  3. Android音频——音量调节
  4. 软件开发生命周期中的设计阶段_软件的生命周期——测试人员必须了解的事
  5. 自然语言处理菜鸟学习笔记(一)
  6. 陀螺专栏势力榜——月榜(5.1-5.31)
  7. AI:大模型领域最新算法SOTA总结、人工智能领域AI工具产品集合分门别类(文本类、图片类、编程类、办公类、视频类、音频类、多模态类)的简介、使用方法(持续更新)之详细攻略
  8. TCP在FIN_WAIT1状态到底能持续多久以及TCP假连接问题
  9. 工程力学(10)—轴向拉伸与压缩二
  10. 云IDE:Eclipse Che:Eclipse下一代IDE