题意:最小生成树是否唯一。
思路:求得次小生成树,如果与最小生成树相等,则不唯一。
求次小生成树的过程:求得最小生成树,依次去掉最小生成树中的边,求的值中的最小值即为次小生成树。
次小生成树可能与最小生成树相等。。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=105;
const int maxe=5050;
int n,m,c;
int f[maxn],used[maxe];
struct Edge
{
int a,b,w,flag;
}edge[maxe];
void Set()
{
for(int i=1;i<=n;i++)
f[i]=i;
}
int find(int x)
{
if(x!=f[x])
f[x]=find(f[x]);
return f[x];
}
bool cmp(Edge a,Edge b)
{
return a.w<b.w;
}
int Kruscal()
{
int i,x,y,ret;
ret=0;c=0;
Set();
for(i=0;i<m&&c<n-1;i++)
{
x=find(edge[i].a);
y=find(edge[i].b);
if(x==y) continue;
f[x]=y;
ret+=edge[i].w;
used[c++]=i;
}
return (c<n-1?0:ret);
}
int SecKruscal()
{
int i,x,y,ret,count;
ret=0;count=0;
Set();
for(i=0;i<m&&count<n-1;i++)
{
x=find(edge[i].a);
y=find(edge[i].b);
if(x==y||edge[i].flag) continue;
f[x]=y;
ret+=edge[i].w;
count++;
}
return (count<n-1?0:ret);
}
int main()
{
int t,i,mst,cmst,ff;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(used,0,sizeof(used));
memset(f,0,sizeof(f));
memset(edge,0,sizeof(edge));
for(i=0;i<m;i++)
{
scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].w);
edge[i].flag=0;
}
sort(edge,edge+m,cmp);
mst=Kruscal();
ff=0;
for(i=0;i<c;i++)
{
edge[used[i]].flag=1;
cmst=SecKruscal();
edge[used[i]].flag=0;
if(cmst==mst&&cmst!=0)//不知道为什么这里必须加上cmst!=0
{
ff=1;
break;
}
}
if(ff==1) printf("Not Unique!\n");
else printf("%d\n",mst);
}
return 0;
}