原题地址

本以为不过是一道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思想 + 访问顺序随机)』的更多相关文章

  1. 解题报告 『[NOI2003]逃学的小孩(树上操作)』

    原题地址 今天翻看集训队巨佬写的一篇有关于树形动规的论文时看到了这道题,但感觉并不需要用动规,求出树的直径再暴力枚举一下就搞出来了. 其实是因为我太弱了,看不懂大佬在写什么orz 代码实现如下: #i ...

  2. 解题报告 『[USACO08NOV]Mixed Up Cows(状压动规)』

    原题地址 观察数据范围:4 ≤ N ≤ 16. 很明显,这是一道状压DP. 定义:dp[i][j]表示队尾为奶牛i,当前含奶牛的状态为j,共有多少组符合条件的队伍. 代码实现如下: #include ...

  3. 解题报告 『机器翻译(vector)』

    原题地址 本想练习一下模拟,不过用vector貌似可以轻松水过?(虽然还是模拟) 但突然发现貌似我并不会判断单词是否在内存中出现过? 最后还是靠度娘解决了. 代码如下: #include <bi ...

  4. 【剑指Offer】调整数组顺序使奇数位于偶数前面 解题报告(Python)

    [牛客网]调整数组顺序使奇数位于偶数前面 解题报告 标签(空格分隔): 牛客网 题目地址:https://www.nowcoder.com/questionTerminal/beb5aa231adc4 ...

  5. 【剑指Offer】翻转单词顺序列 解题报告(Python)

    [剑指Offer]翻转单词顺序列 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews 题 ...

  6. 【剑指Offer】按之字形顺序打印二叉树 解题报告(Python)

    [剑指Offer]按之字形顺序打印二叉树 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-intervie ...

  7. LeetCode 1 Two Sum 解题报告

    LeetCode 1 Two Sum 解题报告 偶然间听见leetcode这个平台,这里面题量也不是很多200多题,打算平时有空在研究生期间就刷完,跟跟多的练习算法的人进行交流思想,一定的ACM算法积 ...

  8. 【NOIP2015】提高day2解题报告

    题目: P1981跳石头 描述 一年一度的“跳石头”比赛又要开始了!这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 N ...

  9. 2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告

    2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh ...

随机推荐

  1. MFC如何在树形图边上添加动态小地图

    MFC如何在树形图边上添加动态小地图 https://www.jianshu.com/p/7b1d828bf5db (简书无法识别缩进的...早知道先在博客园发了) (转载请注明出处) 作者:梦镜谷雨 ...

  2. P2010 回文日期 题解

    这题其实就是纯暴力,暴力,再暴力,毫无技巧可言(总之您怎么乱搞都不会超时QAQ) 首先,根据题意,我们明白每年自多产生一个回文日期,因为对于每年的三百多天,前四位是固定的. 所以,我们只需要进行一个从 ...

  3. OO第十二次作业

    规格设计的发展历史 随着计算机软硬件的发展,代码的复杂程度也在不短增加,随着计算机软件规模日渐庞大,结构化程序设计方法开始无法满足用户的需求,面向对象程序设计产生.面向对象程序设计是一场重大的革命,提 ...

  4. js datagrid 移动去重

    function dataLeft(){ var checkedData = $(listTemplate_right).datagrid('getChecked'); var rows = $(li ...

  5. 20175224 2018-2019-2 《Java程序设计》第八周学习总结

    教材学习内容总结 第十五章 泛型与集合框架 泛型 泛型:目的为建立具有类型安全的集合框架. 泛型类声明:class People<E> class 名称<泛型列表> 链表 定义 ...

  6. selenium中切换浏览器不同tab 的操作

    from selenium import webdriverimport timedriver=webdriver.Chrome()driver.get('http://ui.imdsx.cn/uit ...

  7. L362 When to Bring up Salary During the Job Interview Process

    Money is an awkward topic of conversation for many professionals—even more so when you’re busy tryin ...

  8. SpringBoot项目如何打War包

    首先,需要添加Tomcat启动依赖 <dependency> <groupId>org.springframework.boot</groupId> <art ...

  9. python基础语法二

    迭代 test = "妹子有种冲我来" #可迭代对象 == 被for进行循环获取 for item in test: print(item) break #练习题: test = ...

  10. Linux下Redis4.0.12安装、配置、优化

    一.安装 1.检查gcc环境 执行命令,如果Linux系统没有安装gcc编译器,会提示“Command not found” # gcc -v 安装gcc # yum -y install gcc 以 ...