Spanning tree ยท sub small spanning tree

Secondary spanning tree: Use the prim algorithm to find an MST, and then enumerate the edges not in the MST. When adding the edges, a ring will be formed. We need to delete the edge with the largest weight except the edge just added in the ring. In this way, we can get a smaller tree. So as long as we find the maximum edge weight between two points in the tree and save it, we can do other things Enumeration of all edges not in the tree.

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;
typedef long long ll;
#define maxn 1010
#define MS(a, b) memset(a, b, sizeof(a));

const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
int map[maxn][maxn];
int dis[maxn];
int mmax[maxn][maxn];
bool used[maxn][maxn];
bool vis[maxn];
int pre[maxn];
int n, m;

int Prim() {
    int ans = 0;
    MS(mmax, 0);
    MS(used, false);
    MS(vis, false);
    for (int i = 1; i <= n; i++) {
        dis[i] = map[1][i];
        if (i >= 2) {
            pre[i] = 1;
        }
    }
    pre[1] = 0;
    vis[1] = true;
    for (int ii = 2; ii <= n; ii ++) {
        int min_dis = inf;
        int pos;
        for (int i = 1; i <= n; i++) {
            if (!vis[i] && min_dis > dis[i]) {
                min_dis = dis[i];
                pos = i;
            }
        }
        if (min_dis == inf) {
            return -1;
        }
        else {
            cout << " ads " << min_dis << endl;
            ans += min_dis;
            vis[pos] = true;
            used[pos][pre[pos]] = used[pre[pos]][pos] = true;
            // Edge between two points in the record tree
            for (int i = 1; i <= n; i++) {
                if (vis[i]) {
                    mmax[i][pos] = mmax[pos][i] = max(mmax[i][pre[pos]], dis[pos]);
                    //The maximum edge weight from i to pos is the maximum edge weight in the precursor of i to pos and the maximum value in the distance from the precursor of pos to pos
                }
                else if (!vis[i] && dis[i] > map[pos][i]) {
                    dis[i] = map[pos][i];
                    pre[i] = pos;
                }
            }

        }
    }
    return ans;
}

int Sec_mst(int tot) {
    int ans = inf;
    for (int i = 1; i <= n; i ++) { // Enumerate all edges not in MST and remove the maximum value between two points for comparison
        for (int j = i + 1; j <= n; j ++) {
            if (map[i][j] != inf && !used[i][j]) {
                ans = min(ans, tot + map[i][j] - mmax[i][j]);
            }
        }
    }
    if (ans == inf) {
        return -1;
    }
    else return ans;
}

int main() {
    int T;
    cin >> T;
    while(T--) {
        cin >> n >> m;
        MS(map,inf);
        for (int i = 1; i <= n; i ++) {
            map[i][i] = 0;
        }
        for (int i = 0; i < m; i ++) {
            int a, b, c;
            cin >> a >> b >> c;
            map[a][b] = map[b][a] = c;
        }
        int ans = Prim();
        cout << ans << " asdasd" << endl;
        if (ans == -1) {                  //If not connected, there is no sub small spanning tree
            cout << "Not Unique" << endl;
        }
        else if (ans == Sec_mst(ans)){ // Not unique if MST = = minor
            cout << "Not Unique" << endl;
        }
        else {                        //MST unique
            cout << ans << endl;
        }
    }
}



Posted by jana on Thu, 30 Apr 2020 01:22:04 -0700