LibreOJ链接

Description

给出一个\(n(n\leq12)\)个点\(m(m\leq1000)\)条边的带权无向图,求该图的一棵生成树,使得其边权×该边距根的深度之和最小。

Solution

既然\(n\leq12\),可以猜测是状压DP。

定义\(f[dpt][s][s_1]\)表示一棵深度为\(dpt\),点集为\(s\),最深的(深度为\(dpt\))的点的集合为\(s_1\)的生成树的权值。我们考虑给\(s_1\)接上一些点\(s_2\),从而转移为\(f[dpt+1][s|s_2][s_2]\)。转移方程为:$$f[dpt+1][s|s_2][s_2]=min{ f[dpt][s][s_1]+w[s_1][s_2]\times dpt } \space (s_1\in s,s_2\in \complement_U^s )$$其中\(w[s_1][s_2]\)表示将\(s_2\)接在\(s_1\)上的最小花费,预处理一下即可。

时间复杂度\(O(n\cdot 2^n \cdot 2^k 2^{n-k})=O(n4^n)\)。不过似乎有\(O(n^2 3^n)\)的做法?

Code

//「NOIP2017」宝藏
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int const N=15;
int const S=1<<12;
int const INF=0x3F3F3F3F;
int n,m,ed[N][N]; int U;
int w[S][S],f[2][S][S];
void calW()
{
memset(w,0x3F,sizeof w);
for(int s1=0;s1<=U;s1++) w[s1][0]=0;
for(int s1=0;s1<=U;s1++)
for(int i=0;i<n;i++)
{
int s2=1<<i; if(s1&s2) continue;
for(int j=0;j<n;j++)
if((s1>>j)&1) w[s1][s2]=min(w[s1][s2],ed[i+1][j+1]);
}
for(int s1=0;s1<=U;s1++)
for(int s2=1;s2<=U;s2++)
{
if(s1&s2) continue;
for(int i=1;i<=s2;i<<=1)
if(s2&i) w[s1][s2]=min(w[s1][s2],w[s1][s2^i]+w[s1][i]);
}
}
int main()
{
scanf("%d%d",&n,&m); U=(1<<n)-1;
if(n==1) {puts("0"); return 0;}
memset(ed,0x3F,sizeof ed);
for(int i=1;i<=m;i++)
{
int u,v,c; scanf("%d%d%d",&u,&v,&c);
ed[u][v]=ed[v][u]=min(ed[u][v],c);
}
calW();
int c=0; int ans=INF;
memset(f,0x3F,sizeof f);
for(int i=1;i<=U;i<<=1) f[c][i][i]=0;
for(int dpt=1;dpt<=n;dpt++)
{
c^=1;
for(int s=0;s<=U;s++)
for(int s2=U^s;s2;s2=(s2-1)&(U^s))
{
int res=INF;
for(int s1=s;s1;s1=(s1-1)&s)
if(f[c^1][s][s1]<INF&&w[s1][s2]<INF) res=min(res,f[c^1][s][s1]+w[s1][s2]*dpt);
f[c][s|s2][s2]=res;
}
for(int s2=0;s2<=U;s2++) ans=min(ans,f[c][U][s2]);
}
printf("%d\n",ans);
return 0;
}

P.S.

初始的DP数组要清\(\infty\),而不是\(0\)。

DP数组需要滚动,否则会MLE

我这个做法在LOJ上需要稍微卡一下常,第52行的if就是卡常用的。

NOIP2017 - 宝藏的更多相关文章

  1. 【比赛】NOIP2017 宝藏

    这道题考试的时候就骗了部分分.其实一眼看过去,n范围12,就知道是状压,但是不知道怎么状压,想了5分钟想不出来就枪毙了状压,与AC再见了. 现在写的是状压搜索,其实算是哈希搜索,感觉状压DP理解不了啊 ...

  2. [NOIP2017]宝藏 状压DP

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

  3. [NOIP2017]宝藏 子集DP

    题面:[NOIP2017]宝藏 题面: 首先我们观察到,如果直接DP,因为每次转移的代价受上一个状态到底选了哪些边的影响,因此无法直接转移. 所以我们考虑分层DP,即每次强制现在加入的点的距离为k(可 ...

  4. NOIP2017宝藏 [搜索/状压dp]

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

  5. Luogu 3959 [NOIP2017] 宝藏

    NOIP2017最后一道题 挺难想的状压dp. 受到深度的条件限制,所以一般的状态设计带有后效性,这时候考虑把深度作为一维,这样子可以保证所有状态不重复计算一遍. 神仙预处理:先处理出一个点连到一个集 ...

  6. 洛谷P3959 [NOIP2017]宝藏

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

  7. NOIP2017 宝藏 题解报告【状压dp】

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

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

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

  9. [NOIP2017] 宝藏 【树形DP】【状压DP】

    题目分析: 这个做法不是最优的,想找最优解请关闭这篇博客. 首先容易想到用$f[i][S][j]$表示点$i$为根,考虑$S$这些点,$i$的深度为$j$情况的答案. 转移如下: $f[i][S][j ...

随机推荐

  1. glReadPixel 读取数据错误问题

    glReadPixel 读取数据错误问题 问题:在Android上使用 glReadPixel 读取当前渲染数据,在若干机型(华为P9以及魅族某魅蓝手机)上读取数据失败,glGetError() 没有 ...

  2. Linux实践篇--linux软件的安装,更新与卸载

    本文出处:http://www.cnblogs.com/lhj588/archive/2012/07/17/2595328.html,感谢作者分享. Linux常见的安装为tar,zip,gz,rpm ...

  3. 解决跨站脚本注入,跨站伪造用户请求,sql注入等http安全漏洞

    跨站脚本就是在url上带上恶意的js关键字然后脚本注入了,跨站伪造用户请求就是没有经过登陆,用超链接或者直接url上敲地址进入系统,类似于sql注入这些都是安全漏洞. sql注入 1.参数化查询预处理 ...

  4. JavaScript算法实现排序

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  5. Struts2实现文件下载

    实现文件下载: 1.导包:commons-fileload-xx.jar commons-io-xx.jar 2.jsp页面: <s:iterator value="#session. ...

  6. 怎么使用IDEA

    war 和 war exploded war部署首先通过IDEA生成.war工程文件,然后将WEB工程以包的形式上传到服务器,因此会替代服务器本来同名的web app项目. war exploded模 ...

  7. 解析js中作用域、闭包——从一道经典的面试题开始

    如何理解js中的作用域,闭包,私有变量,this对象概念呢? 就从一道经典的面试题开始吧! 题目:创建10个<a>标签,点击时候弹出相应的序号 先思考一下,再打开看看 //先思考一下你会怎 ...

  8. java web 整合开发王者归来学习总结

    第一章java web开发概述 胖客户端CS,瘦客户端BS(Browser) 网址请求---服务器处理响应-----返回结果-----浏览器显示 CGI可以动态生成页面,但是每个进程都要启动一个CGI ...

  9. copy-webpack-plugin最简使用示例

    拷贝文件的插件 加载插件 $ npm install copy-webpack-plugin --save-dev API new CopyWebpackPlugin(patterns: Array, ...

  10. 同一台机器上多个tomcat启动造成的内存溢出问题的解决方法。

    加下面这句话就行了,我是WIN10+双tomcat+nginx(本地站点),无压力.在编译器的vm option里面加哦. -server -Xms512m -Xmx1024m -XX:PermSiz ...