当前位置: 首页 > news >正文

P3959 [NOIP 2017 提高组] 宝藏 题解

link

题目要求任选图中一点为根,通过拓展道路最终形成一棵树,使得代价总和最小,代价受深度和边权两个因素影响。
容易想到一种爆搜,任选一点为根,每次扫描已选点来不断尝试拓展道路,但这样做太蛋疼了,我们尝试优化。

此时一看数据范围 \(n\le12\),考虑把思路往状压 \(dp\)上引导或寻找类似做法,我们发现:

  1. 在最终形成的树中,同一深度的点不受拓展先后顺序的影响,也就是说我们可以尝试一次性拓展同一深度的点。
  2. 对于已连通的点集 \(s\),我们不关心它的具体形态,只需保证其代价最小,因为在后续拓展中的代价与 \(s\) 的形态无关。

这样的条件启发我们可以 “深度” 为阶段,“点集” 为状态尝试设计 \(dp\)

\(dp\) 状态 \(f_{i,s}\) 为当前拓展到深度 \(i\),状态为 \(s\) 的点均连通时的最小代价,转移方程如下:

\[f_{i,s}=\min_{s \in z 且新点均与 z连通} \{f_{i-1,z} +(i-1)\times cost(z,s) \} \]

其中转移条件 \(s\in z\) 意味着新的一层只能打通原来没有的点,这时就需要用到子集枚举的手段,这样做时间复杂度是 \(O(3^n)\) 的。

\(cost(z,s)\) 表示从旧状态到新状态的代价,这个可以通过预处求得。

最终一层枚举起点,一层枚举深度,再加上子集枚举 \(dp\) 总时间复杂度是 \(O(n^2 3^n)\) 的,可以通过本题。

点击查看代码
const int N=15;
const int M=1<<12;
const int inf=0x3f3f3f3f;
int cost[M][M],n,m,e[N][N];
ll f[N][M],ans=inf;
void init(){for(int s=1;s<(1<<n);s++){   //当前层for(int z=s;z;z=(z-1)&s){//上一层为其子集,保证都是新点转移过来if(s==z) continue;for(int i=0,tmp=inf;i<n;i++,tmp=inf){    //枚举新点if(!( ((s^z)>>i) &1)) continue;for(int j=0;j<n;j++) if((z>>j)&1) tmp=min(tmp,e[j][i]); //选择最短边if(tmp>=inf){cost[z][s]=inf;break;}else cost[z][s]+=tmp;    }}}
}
ll DP(int x){memset(f,0x3f,sizeof(f));f[0][1<<x]=0;//初始免费边ll res=inf;for(int i=1;i<n;i++){for(int s=1;s<(1<<n);s++){for(int z=s;z;z=(z-1)&s){if(s==z) continue;f[i][s]=min(f[i][s],f[i-1][z]+1ll*i*cost[z][s]);}if(s==(1<<n)-1) res=min(res,f[i][s]);}}return res;
}
void xpigeon(){rd(n,m);if(n==1){cout<<0<<'\n';return ;}memset(e,0x3f,sizeof(e));for(int i=0;i<n;i++){e[i][i]=0;}for(int i=1,u,v,w;i<=m;i++){rd(u,v,w);u--,v--;e[u][v]=e[v][u]=min(e[u][v],w);}init();for(int i=0;i<n;i++) ans=min(ans,DP(i));cout<<ans<<'\n';
}
signed main() {ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);xpigeon();return 0;
}
http://www.gsyq.cn/news/10297.html

相关文章:

  • java 框架mybatis_01(
  • 扣子Coze智能体实战:自动采集1000条小红书爆款笔记 ,自动写入飞书多维表格
  • 【CVCVCV】dataloader报错RuntimeError: Caught RuntimeError in DataLoader worker process 0
  • 发送一朵云
  • Spring IO工具类及其用法
  • 实用指南:C++编程学习(第34天)
  • Java集合 - 教程
  • .NET 8 内存泄漏分析
  • Spring中@Primary注解的作用及小demo演示
  • C# 18天 029 依赖注入
  • ruoyi-vue列表显示关联
  • 自定义网关选择后端的微服务实例实现
  • AI 绘画增强版:AI 时代风口项目,助力轻松变现
  • 实用指南:《架构师手记:SpringCloud整合Nacos实战一》
  • SQLCipher数据迁移到PostgreSql详细攻略
  • 百家企业案例征集 | 让测试经验成为行业的共同财富
  • Linux CAN 设备简介
  • 27届春招备战一轮复习--第六期
  • 27届春招备战一轮复习--第七期
  • 工厂打星问题
  • MySQL练习题 - 教程
  • 嵌入式系统arm高级系统调试技能-24./proc/slabinfo 记录解读与内存异常分析
  • vscode的ssh-remote插件经常掉线
  • 记录第一次CCPC(2025)网络赛前后
  • 声像新境:东芝电视以火箭炮SOUND重塑家庭艺术馆新标准
  • c语言数组与指针
  • 开发微信机器人/微信协议/个人微信api接口
  • 深入解析:frp实现内网穿透,公网服务器或云服务器配置frps,本地内网配置frpc
  • 【五行】根据天干、地支、生肖起姓名(9月出生的宝宝可参考)
  • [Android]自定义view - 详解