判断是否存在唯一的最小生成树,可以先求出一棵最小生成树的值,然后如果图边的条数大于n-1的话则可能存在不止一棵最小生成树,挨条边标记不可用看能否得到值跟原来的到一样的生成树,如果有则生成树不唯一,如果没有则生成树唯一。
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
const int maxn=110;
int p[110],rank[110];
bool flag[maxn*maxn];
int del[maxn*maxn];
struct edge
{
int u,v,w;
}e[maxn*maxn];
int n,m;
bool cmp(edge a,edge b)
{
return a.w<b.w;
}
void init()
{
for(int i=0;i<=n;i++)
{
p[i]=i;
rank[i]=0;
}
}
int Find(int x)
{
if(p[x]!=x)
p[x]=Find(p[x]);
return p[x];
}
void Union(int a,int b)
{
if(rank[a]>rank[b])
p[b]=a;
else
{
p[a]=b;
if(rank[a]==rank[b])
rank[b]++;
}
}
int kruskal(int x)
{
int cnt=0;
int sum=0;
int a,b;
int i;
for(i=0;i<m;i++)
{
if(!flag[i])
{
a=Find(e[i].u);
b=Find(e[i].v);
if(a!=b)
{
if(x)
del[cnt]=i;
cnt++;
sum+=e[i].w;
Union(a,b);
if(cnt==n-1)
return sum;
}
}
}
return 0;
}
void work()
{
init();
sort(e,e+m,cmp);
memset(flag,0,sizeof(flag));
memset(del,0,sizeof(del));
int ans=0;
int i;
int num=0;
ans=kruskal(1);
int tmp;
if(m>n-1)
{
for(int i=0;i<n-1;i++)
{
init();
flag[del[i]]=1;
tmp=kruskal(0);
if(ans==tmp)
{
printf("Not Unique!\n");
return;
}
flag[del[i]]=0;
}
}
printf("%d\n",ans);
}
int main()
{
int t;
cin>>t;
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
work();
}
}