枚举子集+预处理优化dp+贪心视角转化成可做dp
https://www.acwing.com/problem/content/531/
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 12, M = 1 << N, INF = 0x3f3f3f3f;
int n, m;
int d[N][N], g[N][M];
int f[M][N];
int main()
{
scanf("%d%d", &n, &m);
memset(d, 0x3f, sizeof d);
for (int i = 0; i < n; i ++ ) d[i][i] = 0;
while (m -- )
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
a --, b -- ;
d[a][b] = d[b][a] = min(d[a][b], c);
}
memset(g, 0x3f, sizeof g);
for (int i = 0; i < n; i ++ )
for (int j = 0; j < 1 << n; j ++ )
for (int k = 0; k < n; k ++ )
if (j >> k & 1)
g[i][j] = min(g[i][j], d[i][k]);
//预处理加速dp转移
memset(f, 0x3f, sizeof f);
for (int i = 0; i < n; i ++ ) f[1 << i][0] = 0;//利用题目条件:初始道路免费
for (int i = 1; i < 1 << n; i ++ )
for (int j = i - 1 & i; j; j = j - 1 & i) // 枚举i的子集
{
int r = i ^ j, cost = 0;
for (int k = 0; k < n; k ++ )
if (j >> k & 1)
{
cost += g[k][r];
if (cost >= INF) break;
}
if (cost >= INF) continue;
for (int k = 1; k < n; k ++ )
f[i][k] = min(f[i][k], f[r][k - 1] + cost * k);
}
int res = INF;
for (int i = 0; i < n; i ++ )
res = min(res, f[(1 << n) - 1][i]);
printf("%d\n", res);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具