Uniqueness of minimum spanning tree (kruskral + sub small spanning tree)

Given a weighted undirected graph, if it is a connected graph, there is at least one minimum spanning tree, and sometimes the minimum spanning tree is not unique. This problem requires you to calculate the total weight of the minimum spanning tree and judge whether it is unique.

Input format:

First, the first line gives two integers: the number of vertices in an undirected graph   N (≤ 500) and number of sides   M. subsequently   M   Row, each row gives two endpoints and weights of an edge in the format of "vertex 1 Vertex 2 weight", where the vertices are from 1 to n   Number, the weight is a positive integer. The topic ensures that the total weight of the minimum spanning tree will not exceed 230.

Output format:

If there is a minimum spanning tree, first output its total weight in the first row and "Yes" in the second row. If the tree is unique, otherwise, "No" is output. If the tree does not exist, "No MST" is output in the first row, and the number of connected sets of the graph is output in the second row.

Input example 1:

5 7
1 2 6
5 1 1
2 3 4
3 4 3
4 1 7
2 4 2
4 5 5

No blank lines at the end

Output example 1:

11
Yes

No blank lines at the end

Input example 2:

4 5
1 2 1
2 3 1
3 4 2
4 1 2
3 1 3

No blank lines at the end

Output example 2:

4
No

No blank lines at the end

Input example 3:

5 5
1 2 1
2 3 1
3 4 2
4 1 2
3 1 3

No blank lines at the end

Output example 3:

No MST
2

  Question 1: can I generate a minimum spanning tree?

——>According to kruskral algorithm, if the number of merges is less than N - 1, it means that it cannot be generated.

Question 2: how many connected sets are there when the minimum spanning tree cannot be generated?

——>Save the ancestor node with a map, and finally output size.

Question 3: how to determine whether the minimum spanning tree is unique?

——>To find the sub small spanning tree, there is only one side difference between the sub small spanning tree and the minimum spanning tree.

          In the process of solving the minimum spanning tree, we use an array to record which edges are used

          For unused edges, the two vertices it connects are called a and b. We add this unused edge to the minimum spanning tree and delete the edge connecting a and b of the original minimum spanning tree. In fact, it is the result minus the length of the edge connecting a and b, plus the length of the newly added edge to judge whether the results are equal in the two cases. If they are equal, it means that the minimum spanning tree is not unique (because the edges used are different).

Code!

#include<iostream>
#include<algorithm>
#include<unordered_map>
#include<cstring>

using namespace std;

const int N = 510;
unordered_map<int, int> fa;
int n, m;
int p[N];

struct Edge
{
    int a, b, c;
    bool operator < (const Edge &w) const
    {
        return c < w.c;
    }
}edge[N * N];

bool st[N]; //Determine whether the edge is used
int g[N];

int find(int x)//Joint search + path compression
{
    if(p[x] != x) p[x] = find(p[x]);
    return p[x];
}

int main()
{
    cin >> n >> m;
    for(int i = 0; i < m; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        edge[i] = {a, b, c};
    }
    sort(edge, edge + m);
    int cnt = 0; //Record merge times
    long long res = 0; //Record results
    for(int i = 1; i <= n; i++) p[i] = i; //Parallel query set initialization
    
    for(int i = 0; i < m; i++)
    {
        auto t = edge[i];
        int x = find(t.a), y = find(t.b);
        if(x != y) //Merge if collection is different
        {
            cnt++; //Number of merges++
            st[i] = true; //The edge is used
            p[x] = y; //Merge set
            res += t.c;
            g[t.a] = g[t.b] = t.c; //Record the side length to determine whether the spanning tree is the only service
        }
    }
    
    if(cnt < n - 1) //Merging times < n - 1 indicates disconnection. (it takes n - 1 times to start at 1 point and continue to join... To n points)
    {
        for(int i = 1; i <= n; i++)
        {
            int t = find(i);
            if(!fa[t]) fa[t] = 1; //Count the ancestors and put them into the map
        }
        cout << "No MST" << endl;
        cout << fa.size() << endl;//Number of ancestors
        return 0;
    }
    cout << res << endl;
    for(int i = 0; i < n; i++)
    {
        if(!st[i]) // I haven't used it
        {
            auto t = edge[i];
            int a = t.a, b = t.b; //Two points connected by edges
            if(res - g[a] + t.c == res) //If the results are the same, the spanning tree is not unique
            {
                puts("No");
                return 0;
            }
        }
    }
    cout << "Yes" << endl;
    return 0;
}

Tags: Algorithm data structure pta

Posted on Sat, 04 Dec 2021 15:01:00 -0500 by hedgehog90