题意
给定一个带权无向图,问该图的最小生成树是否唯一?
分析
第一感觉是做好多次最小生成树就行,但是没怎么多想就感觉复杂度不达标。
然后又想什么关于连通性的东西,统统不行。
但实际上就是先做一次最小生成树,然后在树上依次删去一条边,也就是保证两棵树不完全一样,然后再做最小生成树,判断权值是否与之前相等即可。
其他思路:
上代码
调了好久莫名其妙过了就很离谱
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
struct node
{
int u,v,w,rec;
}e[10010];
int t,n,m,no;
ll ans;
int fa[110];
int cmp(node l,node r)
{
return l.w<r.w;
}
int father(int x)
{
if(fa[x]==x) return x;
else return fa[x]=father(fa[x]);
}
ll kruskal(int ff)
{
for(int i=1;i<=n;i++) fa[i]=i;
ll sum=0;
int tot=0;
for(int i=1;i<=m;i++)
{
if(i==no) continue;
int fx=father(e[i].u);
int fy=father(e[i].v);
if(fx!=fy)
{
fa[fx]=fy;
tot++;
sum+=e[i].w;
if(ff) e[i].rec=1;
}
if(tot==n-1) return sum;
}
if(tot!=n-1) return -1;
}
int main()
{
cin>>t;
while(t--)
{
cin>>n>>m;
for(int i=1;i<=m;i++) cin>>e[i].u>>e[i].v>>e[i].w;
sort(e+1,e+m+1,cmp);
for(int i=1;i<=m;i++) e[i].rec=0;
no=0;
ans=kruskal(1);
int kk=0;
for(int i=1;i<=m;i++)
{
if(e[i].rec==1)
{
no=i;
if(kruskal(0)==ans)
{
cout<<"Not Unique!"<<endl;
kk=1;
break;
}
}
}
if(!kk) cout<<ans<<endl;
}
return 0;
}