宝藏

题目链接

首先,打了一个prim,得了45分

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
#define N 15
#define M 2000
#define INF 0x3f3f3f3f
int n,m,dis[N],dep[N],ans;
int Head[N],tot;
bool vis[N];
struct NODE{
int to,w,next;
} e[M];
struct cmp{
bool operator()(int a,int b){
return dis[a]>dis[b];
}
};
priority_queue< int , vector<int> , cmp > q;
inline int read(){
int x=; char c=getchar();
while(c<''||c>'') c=getchar();
while(''<=c&&c<='') { x=(x<<)+(x<<)+c-''; c=getchar(); }
return x;
}
inline void add(int x,int y,int w){
e[++tot].to=y;
e[tot].w=w;
e[tot].next=Head[x];
Head[x]=tot;
}
int prim(int St){
int sum=;
for(int i=;i<=n;i++){
dis[i]=;
dep[i]=; vis[i]=;
}
dis[St]=dep[St]=;
q.push(St);
while(!q.empty()){
int u=q.top(); q.pop();
if(vis[u]) continue;
vis[u]=; sum+=dis[u];
for(int i=Head[u];i;i=e[i].next){
int v=e[i].to;
if(dis[v]>(dep[u]+)*e[i].w){
dep[v]=dep[u]+;
dis[v]=dep[v]*e[i].w;
}
q.push(v);
}
}
return sum;
}
int main()
{
scanf("%d%d",&n,&m);
int x,y,w;
for(int i=;i<=m;i++){
x=read(); y=read(); w=read();
add(x,y,w); add(y,x,w);
}
ans=INF;
for(int i=;i<=n;i++)
ans=min(ans,prim(i));
printf("%d\n",ans);
return ;
}

然后看到题解里状压DP、模拟退火什么玩意的。。

模拟退火我是不会的

不过随机化什么的好像可以骗一下分

于是将代码改了一点

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<queue>
using namespace std;
#define N 15
#define M 2000
#define INF 0x3f3f3f3f
int n,m,dis[N],dep[N],ans;
int Head[N],tot;
bool vis[N];
struct NODE{
int to,w,next;
} e[M];
struct cmp{
bool operator()(int a,int b){
return dis[a]+rand()>dis[b]+rand();  //非常low的随机化
}
};
priority_queue< int , vector<int> , cmp > q;
inline int read(){
int x=; char c=getchar();
while(c<''||c>'') c=getchar();
while(''<=c&&c<='') { x=(x<<)+(x<<)+c-''; c=getchar(); }
return x;
}
inline void add(int x,int y,int w){
e[++tot].to=y;
e[tot].w=w;
e[tot].next=Head[x];
Head[x]=tot;
}
int prim(int St){
int sum=;
for(int i=;i<=n;i++){
dis[i]=;
dep[i]=; vis[i]=;
}
dis[St]=dep[St]=;
q.push(St);
while(!q.empty()){
int u=q.top(); q.pop();
if(vis[u]) continue;
vis[u]=; sum+=dis[u];
for(int i=Head[u];i;i=e[i].next){
int v=e[i].to;
if(vis[v]) continue;
if(dis[v]>(dep[u]+)*e[i].w){
dep[v]=dep[u]+;
dis[v]=dep[v]*e[i].w;
}
q.push(v);
}
}
return sum;
}
int main()
{
srand();
scanf("%d%d",&n,&m);
int x,y,w;
for(int i=;i<=m;i++){
x=read(); y=read(); w=read();
add(x,y,w); add(y,x,w);
}
ans=INF;
int g=;
while(g--){
srand(rand());
for(int i=;i<=n;i++)
ans=min(ans,prim(i));
}
printf("%d\n",ans);
return ;
}

很迷的是上面代码的复杂度巨大

然后发现一个很严重的问题

邻接表就跟吔了shi一样

我们将邻接表改成邻接矩阵,

又改了一下随机化的方式

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<queue>
using namespace std;
const int MAXN=,MAXM=;
const int INF=0x3f3f3f3f;
int n,m,g[MAXN][MAXN];
int Head[MAXN],num;
struct NODE{
int pos,cost;
};
struct cmp{
bool operator ()(NODE a,NODE b){
return a.cost>b.cost;
}
};
priority_queue< NODE,vector<NODE>,cmp > que;
bool vis[MAXN];
NODE s[MAXM];
int cnt,dis[MAXN],tot[MAXN];
int prim(int S){
int ans=;
memset(vis,,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
que.push(NODE{S,});dis[S]=tot[S]=;
for(int i=;i<=n;i++){
cnt=;
while(!que.empty()&&(vis[que.top().pos]||rand()%(i+)<)){
if(!vis[que.top().pos])
s[++cnt]=que.top();
que.pop();
}
int k;
if(que.empty()) k=s[cnt].pos,cnt--;
else k=que.top().pos,que.pop();
vis[k]=;
ans+=dis[k];
if(ans>INF) return INF;
for(int i=;i<cnt;i++) que.push(s[i]);
for(int i=;i<=n;i++)
if(g[k][i]<INF){
if(dis[i]>(tot[k]+)*g[k][i]){
tot[i]=tot[k]+;
dis[i]=tot[i]*g[k][i];
}
que.push(NODE{i,dis[i]});
}
}
return ans;
}
int main()
{
memset(g,0x3f,sizeof(g));
scanf("%d%d",&n,&m);
int x,y,w;
for(int i=;i<=m;i++){
scanf("%d%d%d",&x,&y,&w);
if(w<g[x][y]) g[x][y]=g[y][x]=w;
}
int ans=INF;
int t=;
while(t--)
for(int i=;i<=n;i++)
ans=min(ans,prim(i));
printf("%d\n",ans);
return ;
}

以上做法都不大靠谱,大家还是状压DP吧(逃

【洛谷P3959】[NOIP2017] 宝藏的更多相关文章

  1. 洛谷P3959 [NOIP2017]宝藏

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

  2. 洛谷 P3959 NOIP2017 宝藏 —— 状压搜索

    题目:https://www.luogu.org/problemnew/show/P3959 搜索: 不是记忆化,而是剪枝: 邻接矩阵存边即可,因为显然没有那么多边. 代码如下: #include&l ...

  3. 洛谷$P3959\ [NOIp2017]$ 宝藏 状压$dp$

    正解:状压$dp$ 解题报告: 传送门$QwQ$ $8102$年的时候就想搞这题了,,,$9102$了$gql$终于开始做这题了$kk$ 发现有意义的状态只有当前选的点集和深度,所以设$f_{i,j} ...

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

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

  5. 【洛谷P3959】宝藏

    题目大意:比较复杂,点 这里 看题. 题解:对于状态压缩 dp 来讲,阶段的确立十分重要.本题中,采用以层次为阶段进行状压 dp. 设状态 \(f[i][S]\) 表示开凿到深度 \(i\),当前已经 ...

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

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

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

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

  8. 洛谷P3959——宝藏

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

  9. 洛谷 P3959 宝藏 解题报告

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

随机推荐

  1. 再探canvas(小球实例)

    之前学习过canvas的一些使用,也用过canvas绘制过时钟, 但是很久不用,有些遗忘了,这里做一个简单的回顾. 在web页面创建一个canvas画布非常简单,如下即可: <canvas id ...

  2. TOJ 1023 Taxi Cab Scheme

    Description Running a taxi station is not all that simple. Apart from the obvious demand for a centr ...

  3. rockmongo配置文件config.php

    使用编辑器(比如notepad或者VI/VIM命令)打开RockMongo安装目录下的config.php,所有的配置都在这里. 认证 mongo_auth 和control_auth 在开始使用Ro ...

  4. Nginx+Keepalived配置

    1. Nginx安装 (1) 环境:分别在2台服务器上部署nginx且步骤一致: 如192.138.86.1和192.138.86.2 (2) 下载官网最新稳定版,地址:https://nginx.o ...

  5. 深入redis内部之redis启动过程之一

    redis作为一个服务器,它的启动是从main函数开始的.redis.c 1. 进程重命名 #ifdef INIT_SETPROCTITLE_REPLACEMENT spt_init(argc, ar ...

  6. 一、hadoop安装与配置

    准备环境: 系统:centos6.5 64位 192.168.211.129   master 192.168.211.131   slave1   在两台服务器上都要配置ssh免密码登录 在192. ...

  7. Codeforces 975D. Ghosts

    Description 给出一条直线 \(a*x+b\) 上的 \(n\) 个点,每一个点有一个速度 \((v_x,v_y)\),求 \(T=[-oo,oo]\) 相交的次数乘以 \(2\) 题面 S ...

  8. java File delete()执行失败原因(转)

    java.io.File里的delete操作很实用也很常用,可以用来删除单独的文件和某一目录.但有时候会出现delete失败的情况,出现这种情况的原因一般有以下几种:1.删除时还有其他程序在使用该文件 ...

  9. jQuery前端数据通用验证库,解放你的双手

    这个简易的验证库,应该能完成90%的基本验证,包括失去焦点时的验证,以及点击提交按钮时的验证.后端的那我就无能为办了,只能是谁用就谁自个儿去写了:). 先上一段调用的代码吧,JS代码说少也不少了,就不 ...

  10. SQL动态配置,动态解析SQL

    在项目中使用SQL动态配置的方式可以让后期的维护和发布后的修改变得更加方便,无论使用那种配置方式都离不开解析成最终真正能执行的SQL.下面代码就是一种比较简单的处理方法,SQL的参数以##括起来. 1 ...