P3959 宝藏 模拟退火。。。
竟然模拟退火能做!我就直接抄代码了,我加了点注释。
题干:
题目描述
参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 nn 个深埋在地下的宝藏屋, 也给出了这 nn 个宝藏屋之间可供开发的 mm 条道路和它们的长度。
小明决心亲自前往挖掘所有宝藏屋中的宝藏。但是,每个宝藏屋距离地面都很远, 也就是说,从地面打通一条到某个宝藏屋的道路是很困难的,而开发宝藏屋之间的道路 则相对容易很多。
小明的决心感动了考古挖掘的赞助商,赞助商决定免费赞助他打通一条从地面到某 个宝藏屋的通道,通往哪个宝藏屋则由小明来决定。
在此基础上,小明还需要考虑如何开凿宝藏屋之间的道路。已经开凿出的道路可以 任意通行不消耗代价。每开凿出一条新道路,小明就会与考古队一起挖掘出由该条道路 所能到达的宝藏屋的宝藏。另外,小明不想开发无用道路,即两个已经被挖掘过的宝藏 屋之间的道路无需再开发。
新开发一条道路的代价是:
$$\mathrm{L} \times \mathrm{K}$$
L代表这条道路的长度,K代表从赞助商帮你打通的宝藏屋到这条道路起点的宝藏屋所经过的 宝藏屋的数量(包括赞助商帮你打通的宝藏屋和这条道路起点的宝藏屋) 。
请你编写程序为小明选定由赞助商打通的宝藏屋和之后开凿的道路,使得工程总代 价最小,并输出这个最小值。
输入输出格式
输入格式:
第一行两个用空格分离的正整数 $n,m$,代表宝藏屋的个数和道路数。
接下来 $m$ 行,每行三个用空格分离的正整数,分别是由一条道路连接的两个宝藏 屋的编号(编号为 $-n$),和这条道路的长度 $v$。
输出格式:
一个正整数,表示最小的总代价。
输入输出样例
输入样例#: 复制
输出样例#: 复制
输入样例#: 复制
输出样例#: 复制
说明
【样例解释1】
小明选定让赞助商打通了$ $ 号宝藏屋。小明开发了道路 $ \to $,挖掘了 $$ 号宝 藏。开发了道路 $ \to $,挖掘了 $$ 号宝藏。还开发了道路 $ \to $,挖掘了$ $号宝 藏。工程总代价为:$ \times + \times + \times = $
【样例解释2】
小明选定让赞助商打通了$ $ 号宝藏屋。小明开发了道路 $ \to $,挖掘了 $$ 号宝 藏。开发了道路 $ \to $,挖掘了 $$ 号宝藏。还开发了道路 $ \to $,挖掘了$ $号宝 藏。工程总代价为:$ \times + \times + \times = $
【数据规模与约定】
对于$ \%$的数据: 保证输入是一棵树,$ \le n \le $,$v \le $ 且所有的 $v $都相等。
对于 $\%$的数据: $ \le n \le $,$ \le m \le $,$v \le $ 且所有的$ v $都相等。
对于$ \%$的数据: $ \le n \le $,$ \le m \le $,$v \le $
对于$ \%$的数据: $ \le n \le $,$ \le m \le $,$v \le $
代码:
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring> #define inf 2147483647 using namespace std;
int n, m;
int map[][];
int depth[];
struct edge
{
int u, v;
};
bool operator < (struct edge a, struct edge b)
{
return depth[a.u]*map[a.u][a.v]>depth[b.u]*map[b.u][b.v];
}
int search(int source)
{
memset(depth, , sizeof(depth));
int vis[]= {};
priority_queue <struct edge> heap;
edge past[];
int p = ;
struct edge e, e2;
int cost = ;
depth[source]=;
vis[source]=;
for (int i = ; i <= n; ++i)
{
if (map[source][i] < inf)
{
e.u = source;
e.v = i;
heap.push(e);
}
}
for (int i = ; i < n; ++i)
{
e = heap.top();//每次取当前最优解
heap.pop();
while (!heap.empty() && ((vis[e.v] || rand() % (n) < ))) //注意这里的判断条件rand()%n<1,即对于一个当前最近点,不选择的几率随着n的增大而减小。
{
if (!vis[e.v]) past[p++] = e;
//对于跳过了的边,以后还用得上,等待选择结束后再压回优先队列中
e = heap.top();
heap.pop();
}
vis[e.v] = ;
depth[e.v] = depth[e.u]+;
if (p-->) //压回优先队列
{
for (; p>=; --p)
{
heap.push(past[p]);
}
}
p = ;
for (int i = ; i <= n; ++i)
{
if (map[e.v][i] < inf && !vis[i])
{
e2.u = e.v;
e2.v = i;
heap.push(e2);
}
}
cost += map[e.u][e.v] * depth[e.u];
}
return cost;
} int main()
{
int a, b, c;
scanf("%d %d", &n, &m);
for (int i = ; i <= n; ++i)
{
for (int j = ; j <= n; ++j)
{
map[i][j] = inf;
}
}
for (int i = ; i < m; ++i)
{
scanf("%d %d %d", &a, &b,&c);
map[a][b] = map[b][a] = min(c, map[a][b]);
}
srand();//瞎写的一个数,应该选什么数都差不多
int MIN = inf;
for (int j = ; j <; ++j)
{
//1000次运行是绝对万无一失的,事实上,400次就够了
for (int i = ; i <= n; ++i)
{
MIN = min(MIN, search(i)); //枚举起点
}
}
printf("%d", MIN);
return ;
}
P3959 宝藏 模拟退火。。。的更多相关文章
- 洛谷P3959 宝藏(模拟退火乱搞)
题意 题目链接 题面好长啊...自己看吧.. Sol 自己想了一个退火的思路,没想到第一次交85,多退了几次就A了哈哈哈 首先把没用的边去掉,然后剩下的边从小到大排序 这样我们就得到了一个选边的序列, ...
- P3959 宝藏
P3959 宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 nn 个深埋在地下的宝藏屋, 也给出了这 nn 个宝藏屋之间可供开发的 mm 条道路和它们的长度. 小明决心亲自前往挖掘 ...
- 洛谷 P3959 宝藏 解题报告
P3959 宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 \(n\) 个深埋在地下的宝藏屋, 也给出了这 \(n\) 个宝藏屋之间可供开发的 \(m\) 条道路和它们的长度. 小 ...
- [luogu]P3959 宝藏[NOIP][状态压缩DP]
[luogu]P3959 宝藏[TREASURE] 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的 ...
- 【题解】P3959 宝藏 - 状压dp / dfs剪枝
P3959 宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝 ...
- [Luogu P3959] 宝藏 (状压DP+枚举子集)
题面 传送门:https://www.luogu.org/problemnew/show/P3959 Solution 这道题的是一道很巧妙的状压DP题. 首先,看到数据范围,应该状压DP没错了. 根 ...
- P3959 宝藏 状压dp
之前写了一份此题关于模拟退火的方法,现在来补充一下状压dp的方法. 其实直接在dfs中状压比较好想,而且实现也很简单,但是网上有人说这种方法是错的...并不知道哪错了,但是就不写了,找了一个正解. 正 ...
- Luogu P3959 宝藏
这道题正解是状压DP,不过我不会所以写一下随机化算法来骗骗分. 听说当时考场上就有很多写prim然后挂掉的神仙,其实这道题是可以prim过的 prim是一种基于贪心的算法,在本题中由于盲目的选择当前最 ...
- 洛谷P3959 宝藏(NOIP2017)(状压DP,子集DP)
洛谷题目传送门 Dalao的题解多数是什么模拟退火.DFS剪枝.\(O(3^nn^2)\)的状压DP之类.蒟蒻尝试着把状压改进了一下使复杂度降到\(O(3^nn)\). 考虑到每条边的贡献跟它所在的层 ...
随机推荐
- VMWare 安装Ubuntu 16.04
1.新建虚拟机 (1)点击文件-->新建虚拟机 (2)选择 自定义(高级)--> 下一步 (3)选择Workstation 12.0 --> 下一步 (4)选择 稍后安装操作系统 - ...
- postgres外部表如何修改源码适配pg升级
postgres中外部表的应用如下: 但是许多在github上的fdw开源代码都是基于9.3以及9.4版本开发,原作者没有随着pg的版本升级而将外部表扩展升级,那只能靠自己去手动修改源码来让这些扩展能 ...
- Java 基础入门随笔(1) JavaSE版——java语言三种技术架构
1.java语言的三种技术架构: J2SE(java 2 Platform Standard Edition):标准版,是为开发普通桌面和商务应用程序提供的解决方案.该技术体系是其他两者的基础,可以完 ...
- (转)Java任务调度框架Quartz入门教程指南(四)Quartz任务调度框架之触发器精讲SimpleTrigger和CronTrigger、最详细的Cron表达式范例
http://blog.csdn.net/zixiao217/article/details/53075009 Quartz的主要接口类是Schedule.Job.Trigger,而触发器Trigge ...
- G. I love Codeforces
G. I love Codeforces 题目大意:给你n个字符串,以及m个喜欢关系,如果u喜欢v,这时候u会把它的用户名改为 I_love_ 加上v当时的用户名 Examples input 5an ...
- SQL上门
学习这个 介绍:SQL 是用于访问和处理数据库的标准的计算机语言.结构化化查询语言! SQL可以分为两大部分:数据操作语言(DML)和数据定义语言(DDL) 数据操作语言:select.update. ...
- 曾经遇过的sql问题
曾经遇过的sql问题 问题一: 语句1: select SUM(level) from Comment 语句2: ELSE SUM(level) END as totalLevel from Comm ...
- vue中对象属性改变视图不更新问题
常规情况下我们在vue实例的data中设置响应数据.但当数据为对象,我们增加或删除对象属性值时,视图并不触发更新,如何解决这个问题呢? let vm = new Vue{ el: '#app', da ...
- POJ 1821 Fence
Fence Time Limit: 1000ms Memory Limit: 30000KB This problem will be judged on PKU. Original ID: 1821 ...
- 暑假集训D19总结
考试 日常爆炸 T1 辣么简单,淼到极致的DP,我竟然打挂了= =,打挂了= =,只拿了75分啊,不能接受啊= = T2 随便找找规律,瞎XX模拟一下就能A的鬼东西,我竟然打了个暴力+Floy ...