【题目描述】

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

小明决心亲自前往挖掘所有宝藏屋中的宝藏。但是,每个宝藏屋距离地面都很远,也就是说,从地面打通一条到某个宝藏屋的道路是很困难的,而开发宝藏屋之间的道路则相对容易很多。

小明的决心感动了考古挖掘的赞助商, 赞助商决定免费赞助他打通一条从地面到某个宝藏屋的通道,通往哪个宝藏屋则由小明来决定。

在此基础上, 小明还需要考虑如何开凿宝藏屋之间的道路。已经开凿出的道路可以任意通行不消耗代价。每开凿出一条新道路,小明就会与考古队一起挖掘出由该条道路所能到达的宝藏屋的宝藏。另外,小明不想开发无用道路,即两个已经被挖掘过的宝藏屋之间的道路无需再开发。

新开发一条道路的代价是:

这条道路的长度 × 从赞助商帮你打通的宝藏屋到这条道路起点的宝藏屋所经过的宝藏屋的数量(包括赞助商帮你打通的宝藏屋和这条道路起点的宝藏屋)。

请你编写程序为小明选定由赞助商打通的宝藏屋和之后开凿的道路,使得工程总代价最小,并输出这个最小值。

【输入格式】

第一行两个用空格分离的正整数 n 和 m,代表宝藏屋的个数和道路数。

接下来 m 行,每行三个用空格分离的正整数,分别是由一条道路连接的两个宝藏屋的编号(编号为 1~n),和这条道路的长度 v。

【输出格式】

输出共一行,一个正整数,表示最小的总代价。

【样例输入1】

4 5
1 2 1
1 3 3
1 4 1
2 3 4
3 4 1

【样例输出1】

4

【样例1提示】

【样例输入2】

4 5
1 2 1
1 3 3
1 4 1
2 3 4
3 4 2

【样例输出2】

5

【样例2提示】

【数据规模】

对于 20%的数据:

保证输入是一棵树, 1≤n≤8, v≤5000 且所有的 v 都相等。

对于 40%的数据:

1≤n≤8, 0≤m≤1000, v≤5000 且所有的 v 都相等。

对于 70%的数据:

1≤n≤8, 0≤m≤1000, v≤ 5000

对于 100%的数据:

1≤n≤12, 0≤m≤1000, v≤ 500000

就把这道NOIP题当成回坑以后第一篇博吧(丢人

数据范围一眼状压DP,然而好像已经忘了DP怎么玩了

一顿胡乱撕烤,脑洞出一个常数巨大的解法。

F[a]表示联通状态为a的最优方案,G[a][]记录状态a的最优方案对应的每个结点深度,枚举边更新

注意到边数远超过完全图,可以预处理删掉无用边。

然而状态挂在了vector上常数过大,在洛谷上T了一个点,开O2可以A,假装自己过掉了(逃

(UPD6.15 突然发现代码放错了 噫呜呜噫)

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
typedef long long LL;
int n,m;
const int mxn=;
const int N=<<;
struct edge{
int u,v,w;
int next;
}e[mxn<<];
int hd[mxn],cnt=;
void add_edge(int u,int v,int w){
e[++cnt].u=u;e[cnt].v=v;e[cnt].w=w;
e[cnt].next=hd[u];hd[u]=cnt;
return;
}
int f[N];
struct node{
int dep[];
};
vector<node>g[N];
// node tt,a;
void solve(){
int tmp=<<n;
for(int i=;i<=n;i++){
f[<<(i-)]=;
tt.dep[i-]=;
g[<<(i-)].push_back(tt);
tt.dep[i-]=;
}
for(int i=;i<tmp;i++){
// printf("tmp:%d %d\n",i,f[i]);
for(int u=;u<n;u++){
if( (i&(<<u)) ){
// printf(" u:%d\n",u);
for(int now=;now<g[i].size();now++){
// printf(" now:%d\n",now);
for(int h=hd[u];h;h=e[h].next){ int v=e[h].v;
// printf(" v:%d\n",v);
if(i&(<<v))continue;
// printf(" v:%d\n",v); int tar=i|(<<v);
// printf(" tar:%d\n",tar);
if(f[tar] > f[i] + e[h].w*g[i][now].dep[u] ){
f[tar] = f[i] + e[h].w*g[i][now].dep[u];
a=g[i][now];
a.dep[v]=g[i][now].dep[u]+;
g[tar].clear();
g[tar].push_back(a);
a.dep[v]=;
}
else if(f[tar]== (f[i] + e[h].w*g[i][now].dep[u])){
a=g[i][now];
a.dep[v]=g[i][now].dep[u]+;
g[tar].push_back(a);
a.dep[v]=;
}
}
}
}
}
}
return;
}
int mp[][];
int main(){
int i,j,u,v,w;
scanf("%d%d",&n,&m);
memset(mp,0x3f,sizeof mp);
for(i=;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
--u;--v;
mp[u][v]=mp[v][u]=min(mp[u][v],w);
}
for(i=;i<n;i++)
for(j=;j<n;j++)
if(mp[i][j]<0x3f3f3f3f)
add_edge(i,j,mp[i][j]);
memset(f,0x3f,sizeof(f));
solve();
printf("%d\n",f[(<<n)-]);
return ;
}

更好的解法是f[a][dep]记录联通状态为a,最深的点深度为dep的最优解,进行转移。

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

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

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

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

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

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

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

  4. 【洛谷P3959】宝藏

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

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

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

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

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

  7. 洛谷P3959——宝藏

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

  8. 【洛谷P3959】[NOIP2017] 宝藏

    宝藏 题目链接 首先,打了一个prim,得了45分 #include<iostream> #include<cstring> #include<cstdio> #i ...

  9. 洛谷 P3959 宝藏 解题报告

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

随机推荐

  1. Teamcity部署.net服务“无法连接到远程服务器”解决方式

    在公司Teamcity上执行自动部署.net服务的时候,发现Teamcity在启动default.aspx的时候报错了,提示:使用“0”个参数调用“GetResponse”时发生异常:“无法连接到远程 ...

  2. php框架的制作原理

    php框架的制作原理 (2012-08-16 14:25:55) 转载▼ 标签: php框架制作 杂谈 分类: php index.php 主入口文件 <?php  define('ISEXIS ...

  3. linux中创建和解压文档的 tar 命令教程

    linux & zip & tar https://www.cnblogs.com/xgqfrms/p/9714161.html 1 linux中的tar命令 tar(磁带归档)命令是 ...

  4. python模拟浏览器爬取数据

    爬虫新手大坑:爬取数据的时候一定要设置header伪装成浏览器!!!! 在爬取某财经网站数据时由于没有设置Header信息,直接被封掉了ip 后来设置了Accept.Connection.User-A ...

  5. Android指纹识别API讲解,让你有更好的用户体验

    我发现了一个比较怪的现象.在iPhone上使用十分普遍的指纹认证功能,在Android手机上却鲜有APP使用,我简单观察了一下,发现Android手机上基本上只有支付宝.微信和极少APP支持指纹认证功 ...

  6. 解题:APIO 2012 派遣

    题面 以报酬为标准维护一个大根堆,从根节点往上合并,每次踢掉若干人直到花费合法后更新答案 #include<cstdio> #include<cstring> #include ...

  7. 解题:洛谷2633 Count on a tree

    题面 在树上建主席树...... 每个点从父亲那里建过来,最后建出来就是从根到$i$这条链上的主席树,查询的时候一边差分一边查询 ($cmt[u]+cmt[v]-cmt[lca(u,v)]-cmt[a ...

  8. 20170520 DP阶段总结

    DP的力量不是无穷的. 但是,因为它叫做“动态规划”,它在OI界如鱼得水.这个“动态”不是指“离线”与“在线”,也不是什么“可持久化”.它只是把问题抽象为一个个“阶段”,在每一个“阶段”中作出或繁或简 ...

  9. Chapter8(IO库) --C++Prime笔记

    1.IO对象不能拷贝或对IO对象赋值,进行IO操作的函数通常是以引用方式传递和返回流. 2.一个流一旦发生错误,其上的后续的IO操作都会失败.代码通常应该在使用一个流之前检查它是否处于良好状态.确定一 ...

  10. golang 中的 time 包的 Ticker

    真实的应用场景是:在测试收包的顺序的时候,加了个 tick 就发现丢包了 那么来看一个应用例子: package main import ( "fmt" "runtime ...