这道题意思是说给一个连通的无向图...问其最小生成树的方案是不是唯一的...所谓唯一就是指满足最小生成树的方案只有一种...思路很简单..先Kruskal找到这个图的最小生成树..并记录边..然后枚举删这些边的某个..看去掉某边后得到的最小生成树的值(其实就是找次小生成树)..若次小生成树的值==最小生成树的值.. 则说明方案不唯一..反之方案唯一..
这里有个很重要的地方一定要留意...那就是得到的次小生成树必须要囊括住所有的点...有trick就是两点间线段的价值为0... 那么有没有这个线段..得到的生成树所需代价不会变..但是就会有可能没有包括所有的点而不是一个真正的生成树..即时这个值与最小生成树的值相等..也不能说最小生成树是不唯一的...
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
int x,y,w;
}line[10005];
int t,n,m,i,p,father[105],ans,way[10005],num,temp,k;
bool cmp(node a,node b)
{
return a.w<b.w;
}
int getfather(int k)
{
if (father[k]==k) return k;
return father[k]=getfather(father[k]);
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d",&t);
while (t--)
{
scanf("%d%d",&n,&m);
for (i=1;i<=m;i++)
scanf("%d%d%d",&line[i].x,&line[i].y,&line[i].w);
for (i=1;i<=n;i++) father[i]=i;
ans=0; num=0;
sort(line+1,line+1+m,cmp);
for (i=1;i<=m;i++)
if (getfather(line[i].x)!=getfather(line[i].y))
{
ans+=line[i].w;
father[father[line[i].y]]=father[line[i].x];
way[++num]=i;
}
for (p=1;p<=num;p++)
{
temp=0; k=1;
for (i=1;i<=n;i++) father[i]=i;
for (i=1;i<=m;i++)
if (i!=way[p] && getfather(line[i].x)!=getfather(line[i].y))
{
temp+=line[i].w;
father[father[line[i].y]]=father[line[i].x];
k++;
}
if (temp==ans && k==n) break;
}
if (m==0) printf("0\n"); else
if (temp==ans && k==n) printf("Not Unique!\n");
else printf("%d\n",ans);
}
return 0;
}