【算法学习笔记】斯坦纳树

【算法学习笔记】斯坦纳树

因为离散的论文打算写这个,所以开始学。
今天先写了模板题,存一下代码,等写论文的时候再来补充原理

模板

#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];
}

习题

P6192 【模板】最小斯坦纳树

posted @ 2022-10-28 17:23  Sakana~  阅读(43)  评论(0编辑  收藏  举报