Is the minimum spanning tree unique

Where is the gate .

Description

Given a connected undirected graph, there are n points and m edges. You need to remove some edges and keep the edge with the smallest length so that the graph is still connected. What is the minimum length of the edge to be kept?
The above problem is the minimum spanning tree problem. In order to increase the difficulty, we also want to know whether the scheme to keep the minimum edge set is unique, that is, whether the edge of the minimum spanning tree is unique. If unique, output the minimum length; if Not Unique, output "Not Unique!".

Input

Enter T in the first line to indicate that there are T groups of test data.
Each group of test data input n,m first, then m lines, each line input ai,bi,ci, indicating that there is a length of ci between ai and bi.

Output

If the minimum spanning tree is unique, output the minimum length; if not, output "Not Unique!".

Sample Input

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

Sample Output

3
Not Unique!

Tips

1 < = T < = 20 1 < = n < = 100 no more than 10000 0 < = CI < = 10000

Solution

  • If the sum of the side length of the secondary spanning tree = minimum spanning tree, the undirected graph MST is not unique
  • For the MST obtained by adding an unused edge, it is necessary to form a ring, delete the largest edge on the ring, and get a sub small spanning tree
  • If an edge is added to the second point, the resulting spanning tree must be equivalent or worse, so only one edge needs to be added

Code

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
struct JOKER{
    int x,y,v;
}e[10007];
int cas,n,m,ans,ans2;
int dis[107],f[107][107],fa[107],a[107][107];
//f[i][j] is the maximum side length in the path between I and j on the minimum spanning tree
bool p[107][107],vis[107];
bool cmp(JOKER a,JOKER b){
    return a.v<b.v;
}
int work(){
    int anst=1e9+7;
    for (int i=1;i<=n;i++)
    for (int j=1;j<=n;j++)
        if (i!=j&&!p[i][j])
            anst=min(anst,ans-f[i][j]+a[i][j]);
    return anst;
}
int main(){
    scanf("%d",&cas);
    while (cas--){
        ans=0;
        memset(vis,0,sizeof(vis));
        memset(dis,0,sizeof(dis));
        memset(fa,0,sizeof(fa));
        memset(p,0,sizeof(p));
        memset(f,0,sizeof(f));

        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
            a[i][j]=1e9+7;
        for (int i=1;i<=m;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            a[x][y]=z; a[y][x]=z;
        }

        vis[1]=1;
        for (int i=2;i<=n;i++){dis[i]=a[1][i]; fa[i]=1;}
        int mm=n-1; dis[1]=0;
        while (mm--){
            int v,minn=1e9+7;
            for (int i=1;i<=n;i++)
                if (vis[i]==0&&dis[i]<minn){minn=dis[i]; v=i;}
            vis[v]=1; ans+=minn;
            //printf("ans=%d\n",ans);
            p[fa[v]][v]=p[v][fa[v]]=1;
            for (int i=1;i<=n;i++)
                if (vis[i]&&i!=v)
                    f[v][i]=f[i][v]=max(f[i][fa[v]],dis[v]);
            for (int i=1;i<=n;i++)
                if (!vis[i]&&a[v][i]<dis[i]){
                    dis[i]=a[v][i];
                    fa[i]=v;
                }
        }

        ans2=work();
        if (ans2==ans) printf("Not Unique!\n");
            else printf("%d\n",ans);
    }
    return 0;
}

Posted by kael.shipman on Sun, 05 Apr 2020 02:13:57 -0700