题意:给n点m边,求最小生成树是否唯一,无重边。
思路:这道题确实可以用次小生成树来做,但这样做反而麻烦了。因为题目指示要求最小生成树是不是只有一种情况,那根本就不用求出次小生成树。用kruskal算法,每加入一条边的时候就往后面的边中看看是不是一样大的边里,连接的集合与前面是一样的,若有,那坑定就no unique了。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int cnt,n,m;
int fa[200];
struct node
{
int u,v,c;
}s[20000];
bool cmp(node a,node b)
{
return a.c<b.c;
}
int find(int x)
{
if(fa[x]!=x)
return find(fa[x]);
return x;
}
void kruskal()
{
int ans=0;
sort(s,s+n,cmp);
for(int i=0;i<m;i++)
{
int x=find(s[i].u);
int y=find(s[i].v);
if(x==y) continue;
for(int j=i+1;j<m;j++)
{
if(s[j].c!=s[i].c) break;
if(find(s[j].u)==x&&find(s[j].v)==y)
{
printf("Not Unique!\n");
return;
}
}
fa[x]=y;
ans+=s[i].c;
}
printf("%d\n",ans);
}
int main()
{
//freopen("t.txt","r",stdin);
int T,x,y,w;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&x,&y,&w);
if(x>y) swap(x,y);
s[i].u=x;s[i].v=y;s[i].c=w;
}
kruskal();
}
return 0;
}