题目大意
给树一颗,求以该树为最小生成树的完全图的最小边权和
思路
既然是最小生成树,显然我们需要用到并查集。同时,我们发现2个联通块相互连接时,花费如下:
设块1点的个数为x,块2为y,该最小生成树的边中连接2块的边权为v。
则为:
(
x
∗
y
−
1
)
∗
(
v
+
1
)
+
v
(x*y-1)*(v+1)+v
(x∗y−1)∗(v+1)+v.
最后,记得long long。
code:
#include<iostream>
#include<algorithm>
using namespace std;
long long n,m,b[100001],s[100001];
struct f{
long long a,b,c;
} a[100001];
long long find(long long u)
{
if (u==b[u]) return u;
b[u]=find(b[u]);
return b[u];
}
bool c(f a,f b)
{
if (a.c<b.c)
{
return 1;
}
else return 0;
}
long long cmp;
int main()
{
cin>>n;
m=n-1;
for (int i=1;i<=n;i++) b[i]=i,s[i]=1;
for (int i=0;i<m;i++)
{
cin>>a[i].a>>a[i].b>>a[i].c;
}
sort(a,a+m,c);
for (int i=0,j=0;i<m;i++)
{
if (find(a[i].a)!=find(a[i].b))
{
cmp+=(long long)((s[find(a[i].a)]*s[find(a[i].b)]-1)*(a[i].c+1));
cmp+=a[i].c;
s[find(a[i].b)]+=s[find(a[i].a)];
b[find(a[i].a)]=find(a[i].b);
}
}
cout<<cmp;
return 0;
}