果真是宝藏题目。

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. C#/VB.NET 合并PDF页面

    本文以C#及vb.net代码为例介绍如何来实现合并PDF页面内容.本文中的合并并非将两个文档简单合并为一个文档,而是将多个页面内容合并到一个页面,目的是减少页面上的空白区域,使页面布局更为紧凑.合理. ...

  2. 《C++Primary》阅读简要总结

    三月份的主要任务之一就是阅读C++Primary这本书,终于在昨天25号下午完成了基础部分的阅读,算是对基础知识整体梳理了一遍,开始看这本书大概可以追溯到去年12月份,在那之前看了C++的入门书籍&l ...

  3. grafana v8.0+ 隐藏表格字段

    Select panel title → Inspect → Panel JSON Set "type" to "table-old" Apply The vi ...

  4. Mysql数据库基础_复习思维导图

    Mysql复习的一个小总结,用xmind写的.(字数没有都不给我发博客) 下面是一些备注 子查询 MySQL子查询称为内部查询,而包含子查询的查询称为外部查询. 子查询可以在使用表达式的任何地方使用, ...

  5. 4┃音视频直播系统之浏览器中通过 WebRTC 进行桌面共享

    一.共享桌面原理 共享桌面在直播系统中是一个必备功能 共享者:每秒钟抓取多次屏幕,每次抓取的屏幕都与上一次抓取的屏幕做比较,取它们的差值,然后对差值进行压缩:如果是第一次抓屏或切幕的情况,即本次抓取的 ...

  6. SQL多表多字段比对方法

    目录 表-表比较 整体思路 找出不同字段的明细 T1/T2两表ID相同的部分,是否存在不同NAME 两表的交集与差集:判断两表某些字段是否相同 两表的交集与差集:找出T2表独有的id 字段-字段比较 ...

  7. awk内建函数

    内建函数 length() 获得字符串长度 cat score.txt Marry 2143 78 84 77 Jack 2321 66 78 45 Tom 2122 48 77 71 Mike 25 ...

  8. 选择器补充与CSS属性

    目录 伪元素选择器 选择器优先级 CSS属性 宽和高 字体样式 文字属性 背景属性 边框属性 display属性 盒子模型 浮动(float) 清除浮动 伪元素选择器 伪元素选择器可以通过CSS操作文 ...

  9. Vue问题

    vue问题 #(1)vouter的addRoutes方法---用户权限 //自定义添加路由方法,防止重复添加路由 #使用后 路由结构 const user = () => import('../ ...

  10. flex布局的总结

    1.开启了flex布局的元素叫: flex container 2.里面的直接子元素叫:flex items(默认情况下,所有item都会在一行显示) 3.display属性由flex和inline- ...