果真是宝藏题目。

0x01 前置芝士

这道题我是真没往状压dp上去想。题目来源

大概看了一下结构。盲猜直接模拟退火!\xyx

所需知识点:模拟退火,贪心。

0x02 分析

题目大意:给你一个图,可能有重边,可能有环。让你在这个图上构出一棵树,使得其权值和最小,每条边的权值定义为:这条边的长度 \(\times\) 这条边的两个端点中深度小的那一个的深度。输出这个最小权值和。

于是我们尝试去构造一个序列 \(a\),然后按照这个序列去构树。

按照这个序列构出的树保证第 \(a[i]\) 个结点一定与第 \(a[j], j \in [1, i - 1]\) 个结点相连。

接下来我们贪心考虑。我们需要使每个点都被拓展到,且权值最小,又因为序列规定,我们需要在已经拓展到的结点去拓展当前结点,那么一定选到当前结点权值最小的已被拓展过的结点进行拓展最优。

即,如果该树满足 \(len(a[i], a[j]) \times dep(a[j]) = \mathrm{Min}\{len(a[i], a[k]) \times dep(a[k]), k \in [1, i - 1]\}\),其中 \(len(x, y)\) 表示结点 \(x\) 到 \(y\) 边的长度,\(dep(x)\) 表示结点 \(x\) 的深度。则此时我们按照这个方式构出的树一定为当前序列下权值和最小的树。

于是题目转换为找到使得构成的树权值和最小的序列,并得到这个序列对应的最小权值和。

这样就是裸的模拟退火了。我们以序列 \(A,A_i = i\) 为初始序列,不断扰动,找到最小值。

调一下参数,可过。

srand: 998244353,SA: 7,delta of temperature: 0.996,initial temperature: 1e4,Target temperature: 0.1

0x03 具体实现

#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std; typedef long long LL;
int Max(int x, int y) {return x > y ? x : y;}
int Min(int x, int y) {return x < y ? x : y;}
int Abs(int x) {return x < 0 ? -x : x;}
void Swap(int &x, int &y) {int t = x; x = y; y = t;} int read() {
int k = 1, x = 0;
char s = getchar();
while (s < '0' || s > '9') {
if (s == '-')
k = -1;
s = getchar();
}
while (s >= '0' && s <= '9') {
x = (x << 3) + (x << 1) + s - '0';
s = getchar();
}
return x * k;
} void write(int x) {
if(x < 0) {
putchar('-');
x = -x;
}
if(x > 9)
write(x / 10);
putchar(x % 10 + '0');
} void print(int x, char s) {
write(x);
putchar(s);
} const int MAXN = 15;
const int INF = 0x3f3f3f3f;
const double q = 0.996;
int mp[MAXN][MAXN], n;
int a[MAXN], new_a[MAXN], dep[MAXN]; int f() {
dep[new_a[1]] = 1;
int res = 0;
for(int i = 2; i <= n; i++) {
int tmp = INF;
for(int j = 1; j < i; j++)
if(mp[new_a[j]][new_a[i]] != INF && mp[new_a[j]][new_a[i]] * dep[new_a[j]] < tmp) {
tmp = mp[new_a[j]][new_a[i]] * dep[new_a[j]];
dep[new_a[i]] = dep[new_a[j]] + 1;
}
if(tmp == INF)
return INF;
res += tmp;
}
return res;
} void Accept(int now, int &ans) {
for(int i = 1; i <= n; i++)
a[i] = new_a[i];
ans = now;
} int SA() {
for(int i = 1; i <= n; i++)
a[i] = i;
int ans = 0x7f7f7f7f;
double t = 1e4;
while(t > 0.1) {
for(int i = 1; i <= n; i++)
new_a[i] = a[i];
Swap(new_a[rand() % n + 1], new_a[rand() % n + 1]);
int now = f(), delta = now - ans;
if(delta < 0)
Accept(now, ans);
else if(exp(-delta / t) * RAND_MAX >= rand())
Accept(now, ans);
t *= q;
}
return ans;
} int main() {
srand(998244353);
memset(mp, 0x3f, sizeof mp);
n = read();
int m = read();
for(int i = 1; i <= m; i++) {
int u = read(), v = read(), w = read();
mp[u][v] = Min(mp[u][v], w);
mp[v][u] = Min(mp[v][u], w);
}
int ans = INF;
for(int i = 1; i <= 7; i++)
ans = Min(ans, SA());
print(ans, '\n');
return 0;
}

Solution -「Luogu 3959」 宝藏的更多相关文章

  1. Solution -「Luogu 5170」类欧几里得算法

    推柿子大赛了属于是. 题目要求三个柿子,不妨分别记为: \[\begin {align} f (a, b, c, n) &= \sum \limits _{i = 0} ^{n} \lfloo ...

  2. Solution -「Luogu 4135」作诗

    写在前面 & 前置芝士   好像是好久没有打理 blog 了.感觉上学期是有点颓.嘶,初三了好好冲一次吧.   那么回到这道题目.你会分块就能看懂. 题目大意   先挂个来自洛谷的 link. ...

  3. Solution -「ARC 104E」Random LIS

    \(\mathcal{Description}\)   Link.   给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...

  4. Solution -「CTS 2019」「洛谷 P5404」氪金手游

    \(\mathcal{Description}\)   Link.   有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...

  5. Solution -「BZOJ 3812」主旋律

    \(\mathcal{Description}\)   Link.   给定含 \(n\) 个点 \(m\) 条边的简单有向图 \(G=(V,E)\),求 \(H=(V,E'\subseteq E)\ ...

  6. Solution -「CF 1342E」Placing Rooks

    \(\mathcal{Description}\)   Link.   在一个 \(n\times n\) 的国际象棋棋盘上摆 \(n\) 个车,求满足: 所有格子都可以被攻击到. 恰好存在 \(k\ ...

  7. 「 Luogu P1231 」 教辅的组成

    题目大意 有 $\text{N1}$ 本书 $\text{N2}$本练习册 $\text{N3}$本答案,一本书只能和一本练习册和一本答案配对.给你一些书和练习册,书和答案的可能的配对关系.问你最多可 ...

  8. 「Luogu 1525」关押罪犯

    更好的阅读体验 Portal Portal1: Luogu Portal2: LibreOJ Description \(S\)城现有两座监狱,一共关押着\(N\)名罪犯,编号分别为\(1 - N\) ...

  9. 「Luogu 2367」语文成绩

    更好的阅读体验 Portal Portal1: Luogu Description 语文老师总是写错成绩,所以当她修改成绩的时候,总是累得不行.她总是要一遍遍地给某些同学增加分数,又要注意最低分是多少 ...

随机推荐

  1. [总结] 零散的 tricks

    对于类似构造方案的题目,先确定其中一些关键位置的方案,然后看是否能较为简单地推出其他位置的方案. 一个长度为 \(n\) 的序列,满足 \[a_1\le-a_4\le a_7\le-a_{10}\le ...

  2. 基于.Net C# 通信开发-串口调试助手

    基于.Net C# 通信开发-串口调试助手 1.概述 串口调试助手,广泛应用于工控领域的数据监控.数据采集.数据分析等工作,可以帮助串口应用设计.开发.测试人员检查所开发的串口应用软硬件的数据收发状况 ...

  3. docker使用详解

    一.docker简介 docker 是一个开源的应用容器引擎,docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化 ...

  4. if判断+while循环

    1.常量​ ​纯大写字母命名常量名,如:AGE_OF_OLDBOY=18 常量的值是可以改变的,如:AGE_OF_OLDBOY=19 2.基本运算符 (1).算术运算​ +.-.*./​ ​      ...

  5. HCNP Routing&Switching之链路聚合

    前文我们了解了MSTP相关话题,回顾清参考https://www.cnblogs.com/qiuhom-1874/p/16268682.html:今天我们来聊一聊链路聚合相关话题: 链路聚合是链路高可 ...

  6. netty系列之:netty中常用的对象编码解码器

    目录 简介 什么是序列化 重构序列化对象 序列化不是加密 使用真正的加密 使用代理 Serializable和Externalizable的区别 netty中对象的传输 ObjectEncoder O ...

  7. WSL2-CentOS7固定IP

    WSL2-CentOS7固定IP WSL2 采用 Hyper-V 的 Internal Virtual Switch,这个虚拟交换机本身是可以设置静态 IP 地址的,但是 WSL2 却自作聪明,在每次 ...

  8. 好客租房22-react组件的两种创建方式(类组件)

    2.2使用类创建组件 类组件:使用ES6的class创建的组件 约定1:类组件必须以大写字母开头 约定2:类组件应该继承react.component父类 从中可以使用父类的方法和属性 约定3:组件必 ...

  9. Java实用类-Enum(枚举)

    1. 历史 ​ 在 JDK 1.5 之前没有枚举类型,那时候一般用接口常量来替代(例如,public static final String male ).JKD1.5之后使用 Java 枚举类型 e ...

  10. CSCMS代码审计

    很久之前审的了. 文章首发于奇安信攻防社区 https://forum.butian.net/share/1626 0x00 前言 CSCMS是一款强大的多功能内容管理系统,采用php5+mysql进 ...