就是求是不是有两个以上最小生成树,先生成一次最小生成树,把每条最小生成边去掉一次,然后看是否还会生成等大小的最小生成树,kruskal存储的是边所以可以优化很多代码,用prime算法也是可以的
//#include<bits\stdc++.h>
#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int VM=120;
const int EM=10010;
struct Edge{
int u,v,cap;
bool operator < (const Edge& a)const {
return cap<a.cap;
}
}edge[EM<<1];
int n,m,flag,ans,father[VM];
void makeset()
{
for(int i=1;i<=n;i++)
father[i]=i;
}
int findset(int x)
{
while(x!=father[x])x=father[x];
return x;
}
void kruskal()
{
makeset();
sort(edge,edge+m);
int path[EM],cnt=0;
ans=0;
for(int i=0;i<m;i++)
{
int u=findset(edge[i].u);
int v=findset(edge[i].v);
if(u!=v)
{
father[v]=u;
ans+=edge[i].cap;
path[cnt++]=i;
}
}
for(int k=0;k<cnt;k++)
{
makeset();
int sum=0,j=0;
for(int i=0;i<m;i++)
{if(i==path[k])continue;
int u=findset(edge[i].u);
int v=findset(edge[i].v);
if(u!=v)
{
father[v]=u;
sum+=edge[i].cap;
j++;
}
}
if(j==n-1&&sum==ans)
{
flag=0;return;
}
}
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].cap);
flag=1;
kruskal();
if(flag) printf("%d\n",ans);
else printf("Not Unique!\n");
}
return 0;
}