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)\). 考虑到每条边的贡献跟它所在的层 ...
随机推荐
- html5——渐变
线性渐变 <style> div { width: 700px; height: 100px; /*方向:从右向左*/ /*起始颜色:黄色*/ /*终止颜色:绿色*/ background ...
- SQL Server建库-建表-建约束
----------------------------------------SQL Server建库-建表-建约束创建School数据库------------------------------ ...
- 10、scala面向对象编程之Trait
1. 将trait作为接口使用 2.trait中定义具体方法 3.trait定义具体字段 4.trait中定义抽象字段 5.为实例对象混入trait 6.trait调用链 7.在trait中覆盖抽象 ...
- c++将bool变量以文字形式打印
#include <iostream> // std::cout, std::boolalpha, std::noboolalpha int main () { bool b = true ...
- Linux 配置JDK + MyEclipse
版本:Ubuntu16.04: jdK: Java SE Development Kit 8u102; My Eclipse: 10.6; JDK配置的细致步骤参见此处. 就一点要注意: 请使用代码进 ...
- Java程序员2016年终总结
回顾2016年, 很庆幸,自己能在2016年年尾找到一份满意的web后台开发工作.这也是我学习编程以来第一份开发工作,我很是珍惜. 还记得大三接触了Java的JFrame编写的坦克大战之后,就对编程产 ...
- Dynamics 365 CRM Connected Field Service 自动发送command
上期降到了怎样部署connected field service(CFS) 我们假设现在IoT 设备是温度监控器, 当温度触发我们之前预设的温度值, IoT会通过IoT Hub 发送IoT Alert ...
- cocos creator destroy方法
node.destroy(),Node.destroyAllChildren并不会立即销毁,实际销毁操作会延迟到当前帧渲染前执行. 这段话可能不明白,但是在Node.destroyAllChildre ...
- POJ3984——迷宫问题
迷宫问题 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 31616 Accepted: 18100 Descriptio ...
- ASP.NET误人子弟教程:在MVC下如何返回图片
这几天忙着一些小事,也没有写什么了,今天,我们来玩一个比较简单的东东.就是在MVC下如何返回图片,相信,在传统WebForm下,大家都晓得怎么弄,方也不限于一种,但是,在架构较为严格的MVC里面,刚开 ...