构造完全图
Posted fangbozhen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了构造完全图相关的知识,希望对你有一定的参考价值。
https://loj.ac/problem/10067
题目描述
??给出一棵最小生成树,求有且仅有这一棵最小生成树的总边权最小的完全图。
思路
??我们考虑对于最小生成树中的一条边,它一定连接着两个连通支(T1,T2),并且是连通(T1、T2)的边中边权最小的,而我们构造完全图时,一定要将(T1、T2)中的节点两两连边,而显然除了最小生成树中的边(设其边权为(v))其余边权均为(v+1)时边权最小。所以我们可以记录每个连通支中的节点数,进行一次(Kruskal),在合并两个连通支时统计答案即可。
代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
struct Edge
{
int x,y,d;
}e[MAXN];
int fa[MAXN],siz[MAXN];
int find(int x)
{
return fa[x]==x?x:fa[x]=find(fa[x]);
}
bool cmp(Edge x,Edge y)
{
return x.d<y.d;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<n;i++)
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].d);
for(int i=1;i<=n;i++)
fa[i]=i,siz[i]=1;
sort(e+1,e+n,cmp);
long long sum=0;
int cnt=0;
for(int i=1;i<n;i++)
{
int fx=find(e[i].x),fy=find(e[i].y);
if(fx!=fy)
{
fa[fx]=fy;
sum+=(long long)(siz[fx]*siz[fy]-1)*(e[i].d+1);
sum+=e[i].d;
siz[fy]+=siz[fx];
cnt++;
if(cnt==n-1)break ;
}
}
printf("%lld",sum);
return 0;
}
以上是关于构造完全图的主要内容,如果未能解决你的问题,请参考以下文章
在 Visual Studio 中创建构造函数的代码片段或快捷方式