解题报告 『宝藏(Prim思想 + 访问顺序随机)』
本以为不过是一道Prim算法模版题,但貌似只能得45分,虽然对我这种蒟蒻来说已经够了。
然而同机房大佬表示可以用模拟退火A了此题,遂习之,终无所获。
然而机缘巧合之下习得了另一种随机算法,于是搭配Prim算法,竟然过了!
首先我们要明确一点:单纯的Prim算法为什么不行。相信聪明的你已经知道了,比如下面就是一个反例:
4 4
1 2 2
1 3 20
2 3 3
3 4 500
Prim算法得出的答案为1508,但是最优解应为507,成功hack。
那么Prim算法是否就真的没有用武之地了呢?非也,我们可以抽出Prim算法的思想——每次取最小。
随机化部分
比如上面那张图,我们按照Prim算法的思想来跑的话,访问顺序如下:
1 => 2 => 3 => 4
但如果访问顺序恰好为:
3 => 4 => 2 => 1
便可以得到最优解507。
基于此思想,我们可以随机访问顺序,然后按照这个访问顺序跑贪心,或许这样不能过,但在大量的随机下,我们十有八九会得出正确的答案,而我们按照一个顺序求出答案仅仅只是n^2的(更何况n最大只有12),所以……
已经没有什么好害怕的了。
代码实现如下:
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (register int i = (a); i <= (b); i++) const long long maxn = + , T = 5e3, INF = 1e9; long long n, m, ans = INF;
long long a[maxn], dis[maxn], edge[maxn][maxn]; long long read() {
long long x = , flag = ;
char ch = ' ';
while (ch != '-' && (ch < '' || ch > '')) ch = getchar();
if (ch == '-') {
flag = ;
ch = getchar();
}
while (ch >= '' && ch <= '') {
x = (x << ) + (x << ) + ch - '';
ch = getchar();
}
return flag ? -x : x;
} void origin() {
rep(i, , n)
rep(j, , n)
edge[i][j] = ((i == j) ? : INF);
rep(i, , n) a[i] = i;//最开始的访问顺序就按照1,2,3,4,...,n.
} long long check() {
memset(dis, , sizeof(dis));
long long cost = , start = a[];//取出第一个点.
dis[start] = ;
rep(i, , n) {
int v = a[i];
int cost_v = INF;
rep(j, , i - ) {
int u = a[j];
if (edge[u][v] * (dis[u] + ) < cost_v) {
cost_v = edge[u][v] * (dis[u] + );
dis[v] = dis[u] + ;
}
}
if (cost_v >= INF) return INF;
cost += cost_v;
}
return cost;
} void work() {
long long tot = T;
while (tot--) {
long long x = rand() % n + , y = rand() % n + ;
swap(a[x], a[y]);//随机交换两个数以达成随机序列.
long long new_ans = check();
ans = min(ans, new_ans);
}
} void write(int x) {
if (x < ) {
putchar('-');
x = -x;
}
if (x > ) write(x / );
putchar(x % + '');
} int main() {
n = read(), m = read();
origin();
rep(i, , m) {
long long u, v, w;
u = read(), v = read(), w = read();
edge[u][v] = min(edge[u][v], w);
edge[v][u] = min(edge[v][u], w);
}
work();
write(ans);
return ;
}
解题报告 『宝藏(Prim思想 + 访问顺序随机)』的更多相关文章
- 解题报告 『[NOI2003]逃学的小孩(树上操作)』
原题地址 今天翻看集训队巨佬写的一篇有关于树形动规的论文时看到了这道题,但感觉并不需要用动规,求出树的直径再暴力枚举一下就搞出来了. 其实是因为我太弱了,看不懂大佬在写什么orz 代码实现如下: #i ...
- 解题报告 『[USACO08NOV]Mixed Up Cows(状压动规)』
原题地址 观察数据范围:4 ≤ N ≤ 16. 很明显,这是一道状压DP. 定义:dp[i][j]表示队尾为奶牛i,当前含奶牛的状态为j,共有多少组符合条件的队伍. 代码实现如下: #include ...
- 解题报告 『机器翻译(vector)』
原题地址 本想练习一下模拟,不过用vector貌似可以轻松水过?(虽然还是模拟) 但突然发现貌似我并不会判断单词是否在内存中出现过? 最后还是靠度娘解决了. 代码如下: #include <bi ...
- 【剑指Offer】调整数组顺序使奇数位于偶数前面 解题报告(Python)
[牛客网]调整数组顺序使奇数位于偶数前面 解题报告 标签(空格分隔): 牛客网 题目地址:https://www.nowcoder.com/questionTerminal/beb5aa231adc4 ...
- 【剑指Offer】翻转单词顺序列 解题报告(Python)
[剑指Offer]翻转单词顺序列 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews 题 ...
- 【剑指Offer】按之字形顺序打印二叉树 解题报告(Python)
[剑指Offer]按之字形顺序打印二叉树 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-intervie ...
- LeetCode 1 Two Sum 解题报告
LeetCode 1 Two Sum 解题报告 偶然间听见leetcode这个平台,这里面题量也不是很多200多题,打算平时有空在研究生期间就刷完,跟跟多的练习算法的人进行交流思想,一定的ACM算法积 ...
- 【NOIP2015】提高day2解题报告
题目: P1981跳石头 描述 一年一度的“跳石头”比赛又要开始了!这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 N ...
- 2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告
2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh ...
随机推荐
- APP压力稳定性测试之monkey入门
1.什么是monkey? Monkey是一个命令行工具,使用安卓调试桥(adb)来运行它,模拟用户触摸屏幕.滑动Trackball.按键等随机事件流来对设备上的程序进行压力测试,检测程序多久的时间会发 ...
- es6 - 一共有 6 种声明变量的方法(var, function, let, const, class, import)
var命令和function命令声明的全局变量,依旧是顶层对象的属性:let命令.const命令.class命令声明的全局变量,不属于顶层对象的属性.也就是说,从 ES6 开始,全局变量将逐步与顶层对 ...
- Idea中:No converter found for return value of type: class java.util.ArrayList:Json格式转换问题
1.在搞SSM框架的时候,前端发送请求后,显示如下错误. @ResponseBody注解进行返回List<对象>的json数据时出现 nested exception is java.la ...
- volatile 与 JVM 指令重排序
前言: 在做单例模式时 有博客在评论区 推荐使用 volatile 关键字 进行修饰 然后用了两天时间查资料看文档 发现涉及的面太广 虽然已经了解为什么要使用 volatile + synchroni ...
- java 的序列化与反序列化
前言: 一直很不理解java的序列化的概念,为什么java对象的序列化要实现 Serializable的接口?或者要实现Externalizable的接口?而且Externalizable 的父类还是 ...
- hadoop.create.0.1
#!/bin/shexit 0 linux单机分布式实验环境数据策略#数据:不同源 -v ,link 各自独立的文件夹#配置:同源,写时复制 存于docker images#程序体,基本不改变.或 ...
- 学习Spring
一.Spring 概述 1.概述 Spring 框架是一个开源的 Java 平台,它最初是由 Rod Johnson 编写的,并且于 2003 年 6 月首次在 Apache 2.0 许可下发布. ...
- VIM学习一: VIM命令学习及插件介绍
一.光标移动及编辑命令(含查找替换) [打开关闭窗口] :e file或:open file 打开新文档 :q或者ctrl+w+q 关闭当前视图的窗口 :tab split ...
- Selenium-java测试环境搭建
1.1背景 Selenium也是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE.Mozilla Firefox.Mozilla ...
- 运维yum语法
软件管理 目前流行的软件包格式: 可直接执行的RPM与DEB.源代码形式的gzip与bzip2压缩包 RPM软件包管理 rpm rpm [选项] *.rpm -i --install instal ...