题解:
次小生成树模板题
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXN = 105;
const int INF = 0x3f3f3f3f;
int n,m,T,mx[MAXN][MAXN],pre[MAXN],vis[MAXN*MAXN];
struct node{ int u,v,w; }edge[MAXN*MAXN];
vector<int> g[MAXN];
inline int Find(int x){ return x==pre[x] ? pre[x]:pre[x]=Find(pre[x]); }
inline bool cmp(node x,node y){ return x.w<y.w; }
inline int Kruskal(){
sort(edge+1,edge+m+1,cmp);
int res=0,cnt=0;
for(int i=1;i<=m;i++){
int xx=Find(edge[i].u),yy=Find(edge[i].v),w=edge[i].w;
if(xx!=yy){
cnt++; res+=w; vis[i]=true;
for(int j=0;j<g[xx].size();j++)
for(int k=0;k<g[yy].size();k++)
mx[g[xx][j]][g[yy][k]] = mx[g[yy][k]][g[xx][j]] = w;
pre[xx]=yy;
for(int j=0;j<g[xx].size();j++)
g[yy].push_back(g[xx][j]);
}
if(cnt==n-1) return res;
}
return res;
}
signed main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) g[i].clear(),g[i].push_back(i),pre[i]=i;
for(int i=1;i<=m;i++) scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w),vis[i]=false;
int MST=Kruskal(),res=INF;
for(int i=1;i<=m;i++)
if(!vis[i])
res = min(res,MST-mx[edge[i].u][edge[i].v]+edge[i].w);
if(res==MST) puts("Not Unique!"); else printf("%d\n",MST);
}
return 0;
}