题意

题目链接

题面好长啊。。。自己看吧。。

Sol

自己想了一个退火的思路,没想到第一次交85,多退了几次就A了哈哈哈

首先把没用的边去掉,然后剩下的边从小到大排序

这样我们就得到了一个选边的序列,我们要求答案强制按照这个序列选

每次退火的时候选两个点交换。

枚举每个点,判断是否能更新答案,

时间复杂度$O(200 * 1000 * N * M)$

/*
*/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<cstring>
#include<algorithm>
#include<vector>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
using namespace std;
const int MAXN = ;
const double eps = 1e-, Dlt = 0.97, INF = 1e9 + ;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
int N, M;
struct Edge {
int u, v, w;
bool operator < (const Edge &rhs) const {
return w < rhs.w;
}
}E[MAXN];
int link[MAXN][MAXN], num, fa[MAXN];
void unionn(int x, int y) {
fa[x] = y;
}
int find(int x) {
if(fa[x] == x) return fa[x];
else return fa[x] = find(fa[x]);
}
vector<Pair> v[MAXN];
int dfs(int x, int cnt, int fa) {
int ans = ;
for(int i = ; i < v[x].size(); i++) {
int to = v[x][i].fi, w = v[x][i].se;
if(to != fa) ans += dfs(to, cnt + , x) + w * cnt;
}
return ans;
}
int solve() {
int cur = INF, tot = , base = ;
for(int i = ; i <= N; i++) fa[i] = i, v[i].clear();
for(int i = ; i <= M; i++) {
int x = E[i].u, y = E[i].v;
int fx = find(x), fy = find(y);
if(fx == fy) continue;
tot++; unionn(fx, fy);
v[x].push_back(MP(y, E[i].w));
v[y].push_back(MP(x, E[i].w));
}
if(tot != N - ) return INF;
for(int i = ; i <= N; i++)
cur = min(cur, dfs(i, , ));
return cur;
}
int main() {
// freopen("testdata.in", "r", stdin);
srand((unsigned)time(NULL));
memset(link, 0x7f, sizeof(link));
N = read(); M = read();
if(N == ) {
puts(""); return ;
}
for(int i = ; i <= M; i++) {
int x = read(), y = read(), w = read();
link[x][y] = min(link[x][y], w);
link[y][x] = min(link[y][x], w);
}
for(int i = ; i <= N; i++)
for(int j = i + ; j <= N; j++)
if(link[i][j] <= INF)
E[++num] = (Edge) {i, j, link[i][j]};
sort(E + , E + num + );
int ans = solve();
int times = ;
while(times--) {
int now = INF;
for(double T = ; T > eps; T *= Dlt) {
int x = rand() % num + , y = rand() % num + ;
//check(x, y);
swap(E[x], E[y]);
int nxt = solve();
if(nxt < ans) {ans = nxt; continue;}
if(nxt < now || ((exp(now - nxt / T) < rand() / RAND_MAX))) {now = nxt; continue;}
swap(E[x], E[y]);
}
}
printf("%d", ans);
return ;
}
/*
4
0 0
0 5000
2354 10000
8787 0
*/

洛谷P3959 宝藏(模拟退火乱搞)的更多相关文章

  1. 洛谷P3959 宝藏(NOIP2017)(状压DP,子集DP)

    洛谷题目传送门 Dalao的题解多数是什么模拟退火.DFS剪枝.\(O(3^nn^2)\)的状压DP之类.蒟蒻尝试着把状压改进了一下使复杂度降到\(O(3^nn)\). 考虑到每条边的贡献跟它所在的层 ...

  2. 洛谷 P3959 宝藏 解题报告

    P3959 宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 \(n\) 个深埋在地下的宝藏屋, 也给出了这 \(n\) 个宝藏屋之间可供开发的 \(m\) 条道路和它们的长度. 小 ...

  3. 洛谷P3959——宝藏

    传送门:QAQQAQ 题意: 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了$n$个深埋在地下的宝藏屋, 也给出了这$n$个宝藏屋之间可供开发的$m$条道路和它们的长度. 小明决心亲自前往挖掘所有 ...

  4. 洛谷P3959 宝藏

    去年NOIP第二毒瘤(并不)的题终于被我攻克了,接下来就只剩noip难度巅峰列队了. 首先说一下三种做法:随机化,状压DP和搜索. 前两种做法我都A了,搜索实在是毒瘤,写鬼啊. 有些带DFS的记忆化搜 ...

  5. 2018.08.09洛谷P3959 宝藏(随机化贪心)

    传送门 回想起了自己赛场上乱搜的20分. 好吧现在也就是写了一个随机化贪心就水过去了,不得不说随机化贪心大法好. 代码: #include<bits/stdc++.h> using nam ...

  6. 洛谷P3959 宝藏(状压dp)

    传送门 为什么感觉状压dp都好玄学……FlashHu大佬太强啦…… 设$f_{i,j}$表示当前选的点集为$i$,下一次要加入的点集为$j$时,新加入的点和原有的点之间的最小边权.具体的转移可以枚举$ ...

  7. 洛谷 P3959 宝藏【状压dp】

    一开始状态设计错了-- 设f[i][s]为当前与根节点联通状况为s,最深深度为i 转移的话枚举当前没有和根联通的点集,预处理出把这些点加进联通块的代价(枚举s中的点和当前点的连边乘以i即可),然后用没 ...

  8. 【题解】洛谷P3959 [NOIP2017TG] 宝藏(状压DP+DFS)

    洛谷P3959:https://www.luogu.org/problemnew/show/P3959 前言 NOIP2017时还很弱(现在也很弱 看出来是DP 但是并不会状压DP 现在看来思路并不复 ...

  9. NOIP2017提高组Day2T2 宝藏 洛谷P3959 状压dp

    原文链接https://www.cnblogs.com/zhouzhendong/p/9261079.html 题目传送门 - 洛谷P3959 题目传送门 - Vijos P2032 题意 给定一个 ...

随机推荐

  1. dataguard类型转换与模式转化

    修改数据保护模式步骤 前提:是否满足转换模式的配置要求 最大保护(Maximum Protection):Standby Database 必须配置Standby Redo Log,Primary D ...

  2. BZOJ1382:[Baltic2001]Mars Maps

    浅谈树状数组与线段树:https://www.cnblogs.com/AKMer/p/9946944.html 题目传送门:https://www.lydsy.com/JudgeOnline/prob ...

  3. C# 序列化反序列化XML的帮助类

    以下是一个包装的用于序列化反序列化XML和C# 对象的类.  public class XmlSerializeHelper<T>     {         #region Serial ...

  4. JavaScript:Map使用

    定义Map /** * Map * */ function Map() { /** 存放键的数组(遍历用到) */ this.keys = new Array(); /** 存放数据 */ this. ...

  5. hibernate学习五 Hibernate补充

    1  MiddleGenIDE可以生成映射类和映射文件. 2

  6. Jenkins Email Extension Plugin 邮件插件

    1:系统管理-管理插件-可选插件  搜索Email 可列出Email Extension Plugin插件 2:选择相应的插件点  下载并安装之后重启,等待 3:安装完后,自己去重启tomcat,先s ...

  7. MFC获取数据的方式

    假设输入框ID是:ID_NUMBER1,ID_NUMBER2,ID_NUMBER3. 获取数据的方式是: int number1,number2,number3; number1 = GetDlgIt ...

  8. 虚拟机中的Linux安装VMware&nbsp;Tools

    虚拟机中的Linux安装VMware Tools Tools" TITLE="虚拟机中的Linux安装VMware Tools" /> Tools" TI ...

  9. day9http协议

    Http协议入门 2.1 什么是http协议 http协议: 对浏览器客户端 和  服务器端 之间数据传输的格式规范 2.2 查看http协议的工具 1)使用火狐的firebug插件(右键->f ...

  10. zkw线段树专题

    题目来自大神博客的线段树专题 http://www.notonlysuccess.com/index.php/segment-tree-complete/ hdu1166 敌兵布阵题意:O(-1)思路 ...