最小斯坦纳树
给定
首先最终肯定选出一棵树。看到
如果最终的树中
否则,就考虑
我们发现,这个式子和求最短路的松弛式子意外的相似:
我们可以通过求最短路的方式求。我们可以在每次从队列中取出
详见代码注释。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 510;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> P;
int n, m, k;
struct edge {
int to, next, w;
} e[maxn << 1];
int head[maxn << 1], tree[maxn << 1], tot;
int dp[maxn][5000], vis[maxn];
int key[maxn];
priority_queue<P, vector<P>, greater<P> > q;
void add(int u, int v, int w) {
e[++tot] = edge{v, head[u], w};
head[u] = tot;
}
void dijkstra(int s) {
// 求解最短路,注意这里的S是给定的状态,dijkstra应当只更新dp[x][s],真正的起点已经在调用之前塞进队列里了
memset(vis, 0, sizeof(vis));
while (!q.empty()) {
P item = q.top();
q.pop();
if (vis[item.second]) continue;
vis[item.second] = 1;
for (int i = head[item.second]; i; i = e[i].next) {
if (dp[tree[i]][s] > dp[item.second][s] + e[i].w) {
//如果tree[i]这个点当作根只有item.second(通过i拓展了若干次的结点得到item.second) 这一个儿子,
//那么根据状态转移式,可以用dp[item.second][s]尝试更新dp[tree[i]][s]
//注意这里即使使用了s之外的关键点为根也无所谓——我们定义的dp是至少不是恰好
dp[tree[i]][s] = dp[item.second][s] + e[i].w;
q.push(P(dp[tree[i]][s], tree[i]));
}
}
}
}
int main() {
memset(dp, INF, sizeof(dp));
scanf("%d %d %d", &n, &m, &k);
int u, v, w;
for (int i = 1; i <= m; i++) {
scanf("%d %d %d", &u, &v, &w);
add(u, v, w);
tree[tot] = v;
add(v, u, w);
tree[tot] = u;
}
for (int i = 1; i <= k; i++) {
scanf("%d", &key[i]);
dp[key[i]][1 << (i - 1)] = 0; //dp初值
}
for (int s = 1; s < (1 << k); s++) {
for (int i = 1; i <= n; i++) {
for (int subs = s & (s - 1); subs; subs = s & (subs - 1)) { //子集枚举,复杂度 O(3^n)
dp[i][s] = min(dp[i][s], dp[i][subs] + dp[i][s ^ subs]); //第一个转移式子
}
if (dp[i][s] != INF) q.push(P(dp[i][s], i)); //如果连起点都到达不了就不必要了(注意这里提前放好起点)
}
dijkstra(s); //拓展,dp[i][S]能尝试更新所有 dp[x][S],x是任意i可达的结点
}
printf("%d\n", dp[key[1]][(1 << k) - 1]); //其实这里根取哪个关键点都无所谓
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!