从一颗MST到另一颗MST只删除修改一条边再添加一条边
cnt1表示在权值相同时可以加入最小生成树的边数
cnt2表示在权值相同时被加入最小生成树的边数
如果可选择=加入则唯一
如果可选择>加入则不唯一
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 200005;
int par[maxn];
struct node{int f,t;long long v;}zdy[maxn];
void Init(int n){for(int i=0;i<=n;i++)par[i]=i;}
int Find(int x)
{
if(x==par[x]) return x;
return par[x]= Find(par[x]);
}
void Union(int x,int y)
{
x=Find(x),y=Find(y);
if(x==y) return;
par[x]=y;
}
bool cmp(node a,node b)
{
return a.v<b.v;
}
int main()
{
int n,m,T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
Init(n);
for(int i=0;i<m;i++) scanf("%d%d%lld",&zdy[i].f,&zdy[i].t,&zdy[i].v);
sort(zdy,zdy+m,cmp);
int cnt1=0,cnt2=0,ans=0;
for(int i=0;i<m;i++)
{
for(int j=i;j<m;j++)
{
if(zdy[i].v!=zdy[j].v) break;
int t1=Find(zdy[j].f),t2=Find(zdy[j].t);
if(t1!=t2) cnt1++;
}
for(int j=i;j<m;j++)
{
if(zdy[i].v!=zdy[j].v) break;
int t1=Find(zdy[j].f),t2=Find(zdy[j].t);
if(t1!=t2) cnt2++,Union(t1,t2),ans+=zdy[j].v;
}
}
if(cnt1>cnt2) printf("Not Unique!\n");
else printf("%d\n",ans);
}
return 0;
}