最小生成树的唯一性,思路是先判断每条边是否有重边,有的话flag=1,否则0.然后第一次求出最小生成树,将结果记录下来,
然后依次去掉第一次使用过的且含有重边的边,再求一次最小生成树,若结果与第一次结果一样,则不唯一。
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node {
int x,y,w;
int flag,used,del;
} e[10010];
int first=0,father[10010];
int n,m,cnt;
bool cmp(node a,node b){
return a.w<b.w;
}
void init(){
for(int i=0;i<=10010;i++){
father[i]=i;
}
}
int check(int x){
int r=x;
while(r!=father[r]){
r=father[r];
}
return r;
}
int combine(int l,int r){
int l1=check(l);
int r1=check(r);
if(l1!=r1){
father[l1]=r1;
return 1;
}
return 0;
}
int kruskal(){
init();
int sum=0,num=0;
for(int i=0;i<m;i++){
if(e[i].del==1)continue;
if(combine(e[i].x,e[i].y)){
sum+=e[i].w;
num++;
if(first)
e[i].used=1;
}
if(num>=n-1)break;
}
return sum;
}
int main(){
int t;
cin>>t;
while(t--){
cnt=0;
cin>>n>>m;
for(int i=0;i<m;i++){
cin>>e[i].x>>e[i].y>>e[i].w;
e[i].del=0;
e[i].used=0;
e[i].flag=0;
}
for(int i=0;i<m;i++){
for(int j=0;j<m;j++){
if(i==j)continue;
if(e[i].w==e[j].w)
e[i].flag=1;
}
}
sort(e,e+m,cmp);
first=1;
int ans=kruskal();
first=0;
int flag=0;
// cout<<"asd"<<endl;
for(int i=0;i<m;i++){
if(e[i].used==1&&e[i].flag==1){
e[i].del=1;
int ans1=kruskal();
// cout<<ans1<<endl;
if(ans1==ans){
flag=1;
puts("Not Unique!");
break;
}
}
e[i].del=0;
}
// cout<<"asd"<<endl;
if(!flag)cout<<ans<<endl;
}
return 0;
}