题意:给定一个连通图,问最小生成树的方案是不是唯一的,不唯一则输出“Not Unique!”,唯一则输出权值;
代码:先求一遍最小生成树的权值 A,然后枚举树的每个边,去掉这个边然后再求一边最小生成树 B,若存在 A=B则证明最小生成树方案不唯一
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#define MAXN 105
using namespace std;
const int N = 100+10;
struct node{
int u,v,w; bool f;
node(){}
node(int _u,int _v,int _w,bool _f){
u=_u,v=_v,w=_w,f=_f;
}
}e[N*N];
bool cmp(node a,node b){
return a.w<b.w;
}
int n,m,fa[N],ans;
int find(int x){
return fa[x]==x?x:fa[x]=find(fa[x]);
}
int Kruskal(int del,int op){
int ans=0,cnt=0;
for(int i=1;i<=m;i++){
if(i==del) continue;
int u=e[i].u,v=e[i].v,w=e[i].w;
int fu=find(u);
int fv=find(v);
if(fu!=fv){
if(op) e[i].f=true;
ans+=w;
fa[fv]=fu;
cnt++;
}
}
if(cnt<n-1) return -1;
else return ans;
}
void init(){
for(int i=1;i<=n;i++) fa[i]=i;
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=1,u,v,w;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
e[i]=node(u,v,w,0);
}
sort(e+1,e+m+1,cmp);
init(),ans=0;
ans=Kruskal(0,1); //求最小生成树的权值,并标记
bool flag=0;
for(int i=1;i<=m;i++)
{
if(!e[i].f) continue;
int sum=0;
init();
sum=Kruskal(i,0);
if(sum==ans){
flag=true;
break;
}
}
if(flag) puts("Not Unique!");
else printf("%d\n",ans);
}
}