【算法学习笔记】斯坦纳树
因为离散的论文打算写这个,所以开始学。
今天先写了模板题,存一下代码,等写论文的时候再来补充原理
模板
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
const int N = 505, inf = 0x3f3f3f3f;
int h[N], e[N*2], ne[N*2], w[N*2], idx;
bool vis[N];
int f[N][5000], S[N], n, m, k;
priority_queue <pii, vector <pii>, greater<pii>> q;
void add (int a, int b, int c) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++;
}
void dijkstra (int s) {
memset (vis, false, sizeof vis);
while (!q.empty ()) {
auto t = q.top ();
int ver = t.second;
q.pop ();
if (vis[ver]) continue;
vis[ver] = true;
for (int i = h[ver]; ~i; i = ne[i]) {
int j = e[i];
if (f[j][s] > f[ver][s] + w[i]) {
f[j][s] = f[ver][s] + w[i];
q.push ({f[ver][s], j});
}
}
}
}
int main () {
cin >> n >> m >> k;
memset (h, -1, sizeof h);
memset (f, 0x3f, sizeof f);
for (int i = 1; i <= m; i++) {
int a, b, c;
cin >> a >> b >> c;
add (a, b, c), add (b, a, c);
}
for (int i = 1; i <= k; i++) cin >> S[i], f[S[i]][1<<(i-1)] = 0;
for (int s = 1; s < (1 << k); s++) {
for (int i = 1; i <= n; i++) {
for (int t = s & (s - 1); t; t = s & (t - 1)) {
f[i][s] = min (f[i][s], f[i][t] + f[i][s ^ t]);
}
if (f[i][s] != inf) q.push ({f[i][s], i});
}
dijkstra (s);
}
cout << f[S[1]][(1<<k) - 1];
}