kruskal判断MST唯一:
需要另外三个标记,k代表是否重边,u代表是否第一次使用,d代表删除该边
// ShellDawn
// POJ1679
// No.7
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#define MM(x) memset(x,0,sizeof(x))
using namespace std;
#define maxn 105
int n,m;
struct Node{
int a;
int b;
int v;
int u;
int k;
int d;
};
Node E[maxn*maxn];
int fa[maxn];
bool cmp(const Node& x,const Node& y){
if(x.v < y.v) return true;
return false;
}
void dok(){
for(int i=1;i<m;i++){
if(E[i].v == E[i-1].v) E[i].k = E[i-1].k = 1;
}
}
int findfa(const int& x){
int y = x;
while(fa[y] != y) y = fa[y];
int z = y;
while(fa[y] != y){
int t = fa[y];
fa[y] = z;
y = t;
}
return z;
}
bool join(const int& x,const int& y){
int fx = findfa(x);
int fy = findfa(y);
if(fx == fy) return false;
if(fx > fy) swap(fx,fy);
fa[fy] = fx;
return true;
}
int kruskal(int F){
for(int i=0;i<=n;i++) fa[i] = i;
int sum = 0;
int cnt = n;
for(int i=0;i<m;i++){
if(E[i].d == 1) continue;
if(join(E[i].a,E[i].b)){
sum+=E[i].v;
if(F==1) E[i].u = 1;
cnt --;
}
if(cnt == 1) break;
}
return sum;
}
int main(){
int T;
cin>>T;
while(T--){
cin>>n>>m;
for(int i=0;i<m;i++){
cin>>E[i].a>>E[i].b>>E[i].v;
E[i].u = E[i].k = E[i].d = 0;
}
sort(E,E+m,cmp);
dok();
int W = kruskal(1);
bool flag = true;
for(int i=0;i<m;i++){
if(E[i].k == 1 && E[i].u == 1){
E[i].d = 1;
int w = kruskal(0);
E[i].d = 0;
if(w == W){
flag = false;
puts("Not Unique!");
break;
}
}
}
if(flag) printf("%d\n",W);
}
return 0;
}