#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<cstdio>
#include<string>
#include<map>
#include<algorithm>
using namespace std;
const int inf=999999;
const int maxn=10000;
int n,m;
struct EDGE
{
int u,v,len;
int vis;
}edge[maxn*100];
int fa[maxn];
int vv[maxn];
bool cmp(EDGE a,EDGE b)
{
return a.len<b.len;
}
int findx(int a)
{
if(fa[a]==a)
return a;
else
return findx(fa[a]);
}
void init()
{
for(int i=0;i<=n;i++)
{
fa[i]=i;
}
}
void Union(int a,int b)
{
int aa=findx(a);
int bb=findx(b);
if(aa<bb)
fa[bb]=aa;
else
fa[aa]=bb;
}
int kruskal()
{
int k=0;
init();
int sum=0;
for(int i=0;i<m;i++)
{
int aa=edge[i].u;
int bb=edge[i].v;
if(findx(aa)!=findx(bb))
{
k++;
edge[i].vis=1;
sum+=edge[i].len;
Union(aa,bb);
}
}
if(k<n-1)
return 0;
else
return sum;
}
int MMST()
{
init();
int sum=0;
int k=0;
for(int i=0;i<m;i++)
{
if(!vv[i])
{
int aa=edge[i].u;
int bb=edge[i].v;
if(findx(aa)!=findx(bb))
{
k++;
sum+=edge[i].len;
Union(aa,bb);
}
}
}
if(k<n-1)
return inf;
else return sum;
}
int main()
{
int cas;
cin>>cas;
while(cas--)
{
cin>>n>>m;
memset(vv,0,sizeof(vv));
for(int i=0;i<m;i++)
{
cin>>edge[i].u>>edge[i].v>>edge[i].len;
edge[i].vis=0;
}
sort(edge,edge+m,cmp);
int sum=kruskal();
int ans=inf;
for(int i=0;i<m;i++)
{
if(edge[i].vis)
{
vv[i]=1;
int tmp=MMST();
ans=min(ans,tmp);
vv[i]=0;
}
}
if(ans==sum)
cout<<"Not Unique!" <<endl;
else
cout<<sum<<endl;
}
return 0;
}
poj (简单题:kruskal判断最小生成树是否唯一--求次小生成树 )
最新推荐文章于 2022-04-06 22:38:22 发布