VJ传送门

直接套次小生成树的板子

看一下和最小生成树是不是相同就可以了

#include <iostream>
#include <algorithm>
using namespace std;
#define int long long
const int maxn=2e5+10; 
const int inf=1e18;
int n,m;
int pre[maxn],deep[maxn],lg[maxn],ok[maxn];
int fa[maxn][21],maxx[maxn][21];
struct p{
	int l,r,w;
}a[maxn<<2];
bool com(p a,p b){
	return a.w < b.w ;
}
struct edge{
	int to,nxt,w;
}d[maxn<<2]; int head[maxn<<2],cnt=1;
void add(int u,int v,int w){d[++cnt] = (edge){v,head[u],w},head[u]=cnt;}
int find(int x){ return x==pre[x]?x:pre[x]=find(pre[x]);}
int kur()
{
	sort(a+1,a+1+m,com);
	for(int i=1;i<=n;i++)	pre[i]=i;
	int ans=0;
	for(int i=1,j=1;i<n;i++)
	for(;j<=m;j++)
	{
		int fl=find(a[j].l),fr=find(a[j].r),w=a[j].w;
		if( fl!=fr )
		{
			add(a[j].l,a[j].r,w); add(a[j].r,a[j].l,w);
			pre[fl]=fr, ans+=w; ok[j]=1;
			break;
		}
	}
	return ans;
}
void dfs(int u,int father)
{
	deep[u]=deep[father]+1,fa[u][0]=father;
	for(int i=1;i<=lg[deep[u]]+1;i++)
	{
		int r = fa[u][i-1];
		fa[u][i]=fa[r][i-1];
		maxx[u][i]=max( maxx[u][i-1],maxx[r][i-1] );
	}
	for(int i=head[u];i;i=d[i].nxt )
	{
		int v=d[i].to;
		if( v==father )	continue;
		maxx[v][0]=d[i].w;
		dfs(v,u);
	}
}
int LCA(int x,int y,int w)
{
	int ans = -inf;
	if( deep[x]<deep[y] )	swap(x,y);
	for(int i=20;i>=0;i--)
		if( deep[fa[x][i]]>=deep[y] )
		{
			ans = max(ans,maxx[x][i] );
			x = fa[x][i];
		}
	if( x==y )	return ans;
	for(int i=20;i>=0;i--)
		if( fa[x][i]!=fa[y][i] )
		{	
			ans = max(ans,maxx[x][i] );
			ans = max(ans,maxx[y][i] );
			x=fa[x][i],y=fa[y][i];
		}
	ans = max(ans,maxx[x][0] );
	ans = max(ans,maxx[y][0] );
	return ans;
}
void init()
{
	cnt=1;
	for(int i=1;i<=m;i++)	ok[i]=0;
	for(int i=0;i<=n;i++)	head[i]=0;
	for(int i=1;i<=n;i++)
		lg[i] = lg[i-1]+((1<<lg[i-1])==i);
}
signed main()
{
	int t; cin >> t;
	while( t-- )
	{	
		cin >> n >> m;
		init();
		for(int i=1;i<=m;i++)
			cin >> a[i].l >> a[i].r >> a[i].w;
		int chu = kur();
		dfs(1,0);
		int ans = inf;
		for(int i=1;i<=m;i++)
		{
			if( ok[i] )	continue;
			int u = a[i].l,v = a[i].r, w = a[i].w;
			ans = min( ans,chu-LCA(u,v,w)+w );
		}
		if( chu!=ans||ans==inf )	cout << chu << endl;
		else	cout << "Not Unique!\n" ;
	}
}