Topic link
Title
Ask whether the minimum spanning tree is unique
Ideas
Find the second smallest spanning tree and see if it is the same as the minimum spanning tree weight
Generally speaking, it is a template problem. I didn’t learn the sub-small spanning tree before writing. I thought of a simple way.
Enumerate the edges of each minimum spanning tree, remove the edges and find the minimum spanning tree again, and compare the weights. However, the shortcomings are obvious, and the complexity is large, and it is necessary to judge whether the picture is connected every time it is deleted.
After learning the algorithm of the next small spanning tree, the general idea is to enumerate the edges that are not in the minimum spanning tree. After adding the minimum spanning tree, a loop will be formed. Delete the largest edge in the loop and compare the answers.
Code
#include<cstdio>
#include<iostream>
#include<iomanip>
#include<map>
#include<string>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<vector>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl "\n"
//#define int long long
using namespace std;
typedef long long ll;
const int maxn=80000;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
int fa[maxn];
vector<int>G[150];
int dis[150][150];
struct Edge{
int u,v;
int w;
int mbl;
}edge[maxn];
void init(int n){
for(int i=0;i<=n;i++){
G[i].clear();
G[i].push_back(i);
fa[i]=i;
}
}
int find(int x){
return x==fa[x]?x:fa[x]=find(fa[x]);
}
void unite(int x,int y){
int fx=find(x),fy=find(y);
if(fx==fy)
return ;
fa[fx]=fy;
int len=G[fx].size();
for(int i=0;i<len;i++)
G[fy].push_back(G[fx][i]);
return ;
}
bool cmp(Edge a,Edge b){
return a.w<b.w;
}
int main(){
IOS
int tn;
bool bl;
cin>>tn;
while(tn--){
memset(edge,0,sizeof edge);
int n,m;
cin>>n>>m;
init(n);
for(int i=1;i<=m;i++)
cin>>edge[i].u>>edge[i].v>>edge[i].w;
int ans=0;
sort(edge+1,edge+1+m,cmp);
for(int i=1;i<=m;i++){
int u=edge[i].u,v=edge[i].v;
int fu=find(u),fv=find(v);
if(fu!=fv){
edge[i].mbl=1;
ans+=edge[i].w;
int len1=G[fu].size(),len2=G[fv].size();
for(int ii=0;ii<len1;ii++)
for(int j=0;j<len2;j++)
dis[G[fu][ii]][G[fv][j]]=dis[G[fv][j]][G[fu][ii]]=edge[i].w;
unite(u,v);
}
}
int t=inf;
for(int i=1;i<=m;i++){
if(edge[i].mbl)
continue;
t=min(t,ans+edge[i].w-dis[edge[i].u][edge[i].v]);
}
if(t>ans)
cout<<ans<<endl;
else
cout<<"Not Unique!"<<endl;
}
return 0;
}